home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqbuild / qcc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-15  |  92.5 KB  |  4,077 lines

  1. #define    LIBQBUILD_CORE
  2. #include "../include/libqbuild.h"
  3. #include "qcc.h"
  4.  
  5. /*=========================================================================== */
  6.  
  7. char sourcedir[NAMELEN_PATH];                    /* 256 */
  8. char destfile[NAMELEN_PATH];                    /* 256 */
  9.  
  10. float *pr_globals = 0;                        /*[MAX_REGS];           // 65536 */
  11. int numpr_globals;                        /* 4 */
  12.  
  13. char *strings = 0;                        /*[MAX_STRINGS];        // 500000 */
  14. int strofs;                            /* 4 */
  15.  
  16. dstatement_t *statements = 0;                    /*[MAX_STATEMENTS];     // 65536 * 8 = 524288 */
  17. int numstatements;                        /* 4 */
  18. int *statement_linenums = 0;                    /*[MAX_STATEMENTS];     // 65536 * 4 = 262144 */
  19.  
  20. dfunction_t *functions = 0;                    /*[MAX_FUNCTIONS];      // 8192 * (28 + 8) = 294912 */
  21. int numfunctions;                        /* 4 */
  22.  
  23. ddef_t *globals = 0;                        /*[MAX_GLOBALS];        // 16384 * 10 = 163840 */
  24. int numglobaldefs;                        /* 4 */
  25.  
  26. ddef_t *fields = 0;                        /*[MAX_FIELDS];         // 1024 * 10 = 10240 */
  27. int numfielddefs;                        /* 4 */
  28.  
  29. char precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];        /* 1024 * 64 = 65536 */
  30. int precache_sounds_block[MAX_SOUNDS];                /* 1024 * 4 = 4096 */
  31. int numsounds;                            /* 4 */
  32.  
  33. char precache_models[MAX_MODELS][MAX_DATA_PATH];        /* 1024 * 64 = 65536 */
  34. int precache_models_block[MAX_SOUNDS];                /* 1024 * 4 = 4096 */
  35. int nummodels;                            /* 4 */
  36.  
  37. char precache_files[MAX_FILES][MAX_DATA_PATH];            /* 1024 * 64 = 65536 */
  38. int precache_files_block[MAX_SOUNDS];                /* 1024 * 4 = 4096 */
  39. int numfiles;                            /* 4 */
  40.  
  41. /*=========================================================================== */
  42.  
  43. int pr_source_line;
  44.  
  45. char *pr_file_p;
  46.  
  47. /* start of current source line */
  48. char *pr_line_start;
  49.  
  50. int pr_bracelevel;
  51.  
  52. char pr_token[2048];
  53. token_type_t pr_token_type;
  54. type_t *pr_immediate_type;
  55. eval_t pr_immediate;
  56.  
  57. char pr_immediate_string[2048];
  58.  
  59. int pr_error_count;
  60.  
  61. char *pr_punctuation[] =
  62. /* longer symbols must be before a shorter partial match */
  63. {"&&", "||", "<=", ">=", "==", "!=", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", ".", "<", ">", "#", "&", "|", NULL};
  64.  
  65. extern def_t def_void;
  66. extern def_t def_string;
  67. extern def_t def_float;
  68. extern def_t def_vector;
  69. extern def_t def_entity;
  70. extern def_t def_field;
  71. extern def_t def_function;
  72. extern def_t def_pointer;
  73.  
  74. /* simple types.  function types are dynamically allocated */
  75. type_t type_void =
  76. {ev_void, &def_void};
  77. type_t type_string =
  78. {ev_string, &def_string};
  79. type_t type_float =
  80. {ev_float, &def_float};
  81. type_t type_vector =
  82. {ev_vector, &def_vector};
  83. type_t type_entity =
  84. {ev_entity, &def_entity};
  85. type_t type_field =
  86. {ev_field, &def_field};
  87. type_t type_function =
  88. {ev_function, &def_function, NULL, &type_void};
  89.  
  90. /* type_function is a void() function used for state defs */
  91. type_t type_pointer =
  92. {ev_pointer, &def_pointer};
  93.  
  94. type_t type_floatfield =
  95. {ev_field, &def_field, NULL, &type_float};
  96.  
  97. int type_size[8] =
  98. {1, 1, 1, 3, 1, 1, 1, 1};
  99.  
  100. def_t def_void =
  101. {&type_void, "temp"};
  102. def_t def_string =
  103. {&type_string, "temp"};
  104. def_t def_float =
  105. {&type_float, "temp"};
  106. def_t def_vector =
  107. {&type_vector, "temp"};
  108. def_t def_entity =
  109. {&type_entity, "temp"};
  110. def_t def_field =
  111. {&type_field, "temp"};
  112. def_t def_function =
  113. {&type_function, "temp"};
  114. def_t def_pointer =
  115. {&type_pointer, "temp"};
  116.  
  117. def_t def_ret, def_parms[MAX_PARMS];
  118.  
  119. def_t *def_for_type[8] =
  120. {&def_void, &def_string, &def_float, &def_vector, &def_entity, &def_field, &def_function, &def_pointer};
  121.  
  122. /*=========================================================================== */
  123.  
  124. pr_info_t pr;
  125. def_t *pr_global_defs[MAX_REGS];
  126.  
  127.                            /* to find def for a global variable */
  128.  
  129. int pr_edict_size;
  130.  
  131. char pr_parm_names[MAX_PARMS][MAX_NAME];
  132.  
  133. /*======================================== */
  134.  
  135. /* the function being parsed, or NULL */
  136. def_t *pr_scope;
  137.  
  138. bool pr_dumpasm;
  139.  
  140. /* filename for function definition */
  141. string_t s_file;
  142.  
  143. /* for tracking local variables vs temps */
  144. int locals_end;
  145.  
  146. /* longjump with this on parse error */
  147. jmp_buf pr_parse_abort;
  148.  
  149. char pr_framemacros[MAX_FRAMES][16];
  150. int pr_nummacros;
  151.  
  152. /*======================================== */
  153.  
  154. opcode_t pr_opcodes[] =
  155. {
  156.   {"<DONE>", "DONE", -1, FALSE, &def_entity, &def_field, &def_void},
  157.  
  158.   {"*", "MUL_F", 2, FALSE, &def_float, &def_float, &def_float},
  159.   {"*", "MUL_V", 2, FALSE, &def_vector, &def_vector, &def_float},
  160.   {"*", "MUL_FV", 2, FALSE, &def_float, &def_vector, &def_vector},
  161.   {"*", "MUL_VF", 2, FALSE, &def_vector, &def_float, &def_vector},
  162.  
  163.   {"/", "DIV", 2, FALSE, &def_float, &def_float, &def_float},
  164.  
  165.   {"+", "ADD_F", 3, FALSE, &def_float, &def_float, &def_float},
  166.   {"+", "ADD_V", 3, FALSE, &def_vector, &def_vector, &def_vector},
  167.  
  168.   {"-", "SUB_F", 3, FALSE, &def_float, &def_float, &def_float},
  169.   {"-", "SUB_V", 3, FALSE, &def_vector, &def_vector, &def_vector},
  170.  
  171.   {"==", "EQ_F", 4, FALSE, &def_float, &def_float, &def_float},
  172.   {"==", "EQ_V", 4, FALSE, &def_vector, &def_vector, &def_float},
  173.   {"==", "EQ_S", 4, FALSE, &def_string, &def_string, &def_float},
  174.   {"==", "EQ_E", 4, FALSE, &def_entity, &def_entity, &def_float},
  175.   {"==", "EQ_FNC", 4, FALSE, &def_function, &def_function, &def_float},
  176.  
  177.   {"!=", "NE_F", 4, FALSE, &def_float, &def_float, &def_float},
  178.   {"!=", "NE_V", 4, FALSE, &def_vector, &def_vector, &def_float},
  179.   {"!=", "NE_S", 4, FALSE, &def_string, &def_string, &def_float},
  180.   {"!=", "NE_E", 4, FALSE, &def_entity, &def_entity, &def_float},
  181.   {"!=", "NE_FNC", 4, FALSE, &def_function, &def_function, &def_float},
  182.  
  183.   {"<=", "LE", 4, FALSE, &def_float, &def_float, &def_float},
  184.   {">=", "GE", 4, FALSE, &def_float, &def_float, &def_float},
  185.   {"<", "LT", 4, FALSE, &def_float, &def_float, &def_float},
  186.   {">", "GT", 4, FALSE, &def_float, &def_float, &def_float},
  187.  
  188.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_float},
  189.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_vector},
  190.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_string},
  191.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_entity},
  192.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_field},
  193.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_function},
  194.  
  195.   {".", "ADDRESS", 1, FALSE, &def_entity, &def_field, &def_pointer},
  196.  
  197.   {"=", "STORE_F", 5, TRUE, &def_float, &def_float, &def_float},
  198.   {"=", "STORE_V", 5, TRUE, &def_vector, &def_vector, &def_vector},
  199.   {"=", "STORE_S", 5, TRUE, &def_string, &def_string, &def_string},
  200.   {"=", "STORE_ENT", 5, TRUE, &def_entity, &def_entity, &def_entity},
  201.   {"=", "STORE_FLD", 5, TRUE, &def_field, &def_field, &def_field},
  202.   {"=", "STORE_FNC", 5, TRUE, &def_function, &def_function, &def_function},
  203.  
  204.   {"=", "STOREP_F", 5, TRUE, &def_pointer, &def_float, &def_float},
  205.   {"=", "STOREP_V", 5, TRUE, &def_pointer, &def_vector, &def_vector},
  206.   {"=", "STOREP_S", 5, TRUE, &def_pointer, &def_string, &def_string},
  207.   {"=", "STOREP_ENT", 5, TRUE, &def_pointer, &def_entity, &def_entity},
  208.   {"=", "STOREP_FLD", 5, TRUE, &def_pointer, &def_field, &def_field},
  209.   {"=", "STOREP_FNC", 5, TRUE, &def_pointer, &def_function, &def_function},
  210.  
  211.   {"<RETURN>", "RETURN", -1, FALSE, &def_void, &def_void, &def_void},
  212.  
  213.   {"!", "NOT_F", -1, FALSE, &def_float, &def_void, &def_float},
  214.   {"!", "NOT_V", -1, FALSE, &def_vector, &def_void, &def_float},
  215.   {"!", "NOT_S", -1, FALSE, &def_vector, &def_void, &def_float},
  216.   {"!", "NOT_ENT", -1, FALSE, &def_entity, &def_void, &def_float},
  217.   {"!", "NOT_FNC", -1, FALSE, &def_function, &def_void, &def_float},
  218.  
  219.   {"<IF>", "IF", -1, FALSE, &def_float, &def_float, &def_void},
  220.   {"<IFNOT>", "IFNOT", -1, FALSE, &def_float, &def_float, &def_void},
  221.  
  222.   /* calls returns REG_RETURN */
  223.   {"<CALL0>", "CALL0", -1, FALSE, &def_function, &def_void, &def_void},
  224.   {"<CALL1>", "CALL1", -1, FALSE, &def_function, &def_void, &def_void},
  225.   {"<CALL2>", "CALL2", -1, FALSE, &def_function, &def_void, &def_void},
  226.   {"<CALL3>", "CALL3", -1, FALSE, &def_function, &def_void, &def_void},
  227.   {"<CALL4>", "CALL4", -1, FALSE, &def_function, &def_void, &def_void},
  228.   {"<CALL5>", "CALL5", -1, FALSE, &def_function, &def_void, &def_void},
  229.   {"<CALL6>", "CALL6", -1, FALSE, &def_function, &def_void, &def_void},
  230.   {"<CALL7>", "CALL7", -1, FALSE, &def_function, &def_void, &def_void},
  231.   {"<CALL8>", "CALL8", -1, FALSE, &def_function, &def_void, &def_void},
  232.  
  233.   {"<STATE>", "STATE", -1, FALSE, &def_float, &def_float, &def_void},
  234.  
  235.   {"<GOTO>", "GOTO", -1, FALSE, &def_float, &def_void, &def_void},
  236.  
  237.   {"&&", "AND", 6, FALSE, &def_float, &def_float, &def_float},
  238.   {"||", "OR", 6, FALSE, &def_float, &def_float, &def_float},
  239.  
  240.   {"&", "BITAND", 2, FALSE, &def_float, &def_float, &def_float},
  241.   {"|", "BITOR", 2, FALSE, &def_float, &def_float, &def_float},
  242.  
  243.   {NULL}
  244. };
  245.  
  246. def_t *PR_Expression(register int priority);
  247.  
  248. def_t junkdef;
  249.  
  250. /*
  251.  * ===========================================================================
  252.  * qcc
  253.  * ===========================================================================
  254.  */
  255.  
  256. /* CopyString returns an offset from the string heap */
  257. int CopyString(register char *str)
  258. {
  259.   int old;
  260.  
  261.   old = strofs;
  262.   __strcpy(strings + strofs, str);
  263.   strofs += __strlen(str) + 1;
  264.   return old;
  265. }
  266.  
  267. void PrintStrings(void)
  268. {
  269.   int i, l, j;
  270.  
  271.   for (i = 0; i < strofs; i += l) {
  272.     l = __strlen(strings + i) + 1;
  273.     mprintf("%5i : ", i);
  274.     for (j = 0; j < l; j++) {
  275.       if (strings[i + j] == '\n') {
  276.     putchar('\\');
  277.     putchar('n');
  278.       }
  279.       else
  280.     putchar(strings[i + j]);
  281.     }
  282.     mprintf("\n");
  283.   }
  284. }
  285.  
  286. void PrintFunctions(void)
  287. {
  288.   int i, j;
  289.   dfunction_t *d;
  290.  
  291.   for (i = 0; i < numfunctions; i++) {
  292.     d = &functions[i];
  293.     mprintf("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start);
  294.     for (j = 0; j < d->numparms; j++)
  295.       mprintf("%i ", d->parm_size[j]);
  296.     mprintf(")\n");
  297.   }
  298. }
  299.  
  300. void PrintFields(void)
  301. {
  302.   int i;
  303.   ddef_t *d;
  304.  
  305.   for (i = 0; i < numfielddefs; i++) {
  306.     d = &fields[i];
  307.     mprintf("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  308.   }
  309. }
  310.  
  311. void PrintGlobals(void)
  312. {
  313.   int i;
  314.   ddef_t *d;
  315.  
  316.   for (i = 0; i < numglobaldefs; i++) {
  317.     d = &globals[i];
  318.     mprintf("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  319.   }
  320. }
  321.  
  322. /*=========================================================================== */
  323.  
  324. void PrecacheSound(register def_t * e, register int ch)
  325. {
  326.   char *n;
  327.   int i;
  328.  
  329.   if (!e->ofs)
  330.     return;
  331.   n = G_STRING(e->ofs);
  332.   for (i = 0; i < numsounds; i++)
  333.     if (!__strcmp(n, precache_sounds[i]))
  334.       return;
  335.   if (numsounds == MAX_SOUNDS)
  336.     eprintf("PrecacheSound: numsounds == MAX_SOUNDS");
  337.   __strcpy(precache_sounds[i], n);
  338.   if (ch >= '1' && ch <= '9')
  339.     precache_sounds_block[i] = ch - '0';
  340.   else
  341.     precache_sounds_block[i] = 1;
  342.   numsounds++;
  343. }
  344.  
  345. void PrecacheModel(register def_t * e, register int ch)
  346. {
  347.   char *n;
  348.   int i;
  349.  
  350.   if (!e->ofs)
  351.     return;
  352.   n = G_STRING(e->ofs);
  353.   for (i = 0; i < nummodels; i++)
  354.     if (!__strcmp(n, precache_models[i]))
  355.       return;
  356.   if (numsounds == MAX_SOUNDS)
  357.     eprintf("PrecacheModels: numsounds == MAX_SOUNDS");
  358.   __strcpy(precache_models[i], n);
  359.   if (ch >= '1' && ch <= '9')
  360.     precache_models_block[i] = ch - '0';
  361.   else
  362.     precache_models_block[i] = 1;
  363.   nummodels++;
  364. }
  365.  
  366. void PrecacheFile(register def_t * e, register int ch)
  367. {
  368.   char *n;
  369.   int i;
  370.  
  371.   if (!e->ofs)
  372.     return;
  373.   n = G_STRING(e->ofs);
  374.   for (i = 0; i < numfiles; i++)
  375.     if (!__strcmp(n, precache_files[i]))
  376.       return;
  377.   if (numfiles == MAX_FILES)
  378.     eprintf("PrecacheFile: numfiles == MAX_FILES");
  379.   __strcpy(precache_files[i], n);
  380.   if (ch >= '1' && ch <= '9')
  381.     precache_files_block[i] = ch - '0';
  382.   else
  383.     precache_files_block[i] = 1;
  384.   numfiles++;
  385. }
  386.  
  387. /*=========================================================================== */
  388.  
  389. bool ExitData(void)
  390. {
  391.   kfree();
  392.  
  393.   return FALSE;
  394. }
  395.  
  396. bool InitData(void)
  397. {
  398.   int i;
  399.  
  400.   if (!(pr_globals = (float *)kmalloc(MAX_REGS * sizeof(float))))
  401.       return ExitData();
  402.   if (!(strings = (char *)kmalloc(MAX_STRINGS * sizeof(char))))
  403.       return ExitData();
  404.  
  405.   if (!(statements = (dstatement_t *) kmalloc(MAX_STATEMENTS * sizeof(dstatement_t))))
  406.     return ExitData();
  407.   if (!(statement_linenums = (int *)kmalloc(MAX_STATEMENTS * sizeof(int))))
  408.       return ExitData();
  409.  
  410.   if (!(functions = (dfunction_t *) kmalloc(MAX_FUNCTIONS * sizeof(dfunction_t))))
  411.     return ExitData();
  412.   if (!(globals = (ddef_t *) kmalloc(MAX_GLOBALS * sizeof(ddef_t))))
  413.     return ExitData();
  414.   if (!(fields = (ddef_t *) kmalloc(MAX_FIELDS * sizeof(ddef_t))))
  415.     return ExitData();
  416.  
  417.   numstatements = 1;
  418.   strofs = 1;
  419.   numfunctions = 1;
  420.   numglobaldefs = 1;
  421.   numfielddefs = 1;
  422.  
  423.   def_ret.ofs = OFS_RETURN;
  424.   for (i = 0; i < MAX_PARMS; i++)
  425.     def_parms[i].ofs = OFS_PARM0 + 3 * i;
  426.  
  427.   return TRUE;
  428. }
  429.  
  430. void WriteData(register int crc)
  431. {
  432.   def_t *def;
  433.   ddef_t *dd;
  434.   dprograms_t progs;
  435.   HANDLE h;
  436.   int i;
  437.  
  438.   for (def = pr.def_head; def; def = def->next) {
  439.     if (def->type->type == ev_function) {
  440.       /*
  441.        * df = &functions[numfunctions];
  442.        * numfunctions++;
  443.        */
  444.     }
  445.     else if (def->type->type == ev_field) {
  446.       dd = &fields[numfielddefs];
  447.       numfielddefs++;
  448.       dd->type = def->type->aux_type->type;
  449.       dd->s_name = CopyString(def->name);
  450.       dd->ofs = G_INT(def->ofs);
  451.     }
  452.     dd = &globals[numglobaldefs];
  453.     numglobaldefs++;
  454.     dd->type = def->type->type;
  455.     if (!def->initialized
  456.     && def->type->type != ev_function
  457.     && def->type->type != ev_field
  458.     && def->scope == NULL)
  459.       dd->type |= DEF_SAVEGLOBGAL;
  460.     dd->s_name = CopyString(def->name);
  461.     dd->ofs = def->ofs;
  462.   }
  463.  
  464.   /*
  465.    * PrintStrings ();
  466.    * PrintFunctions ();
  467.    * PrintFields ();
  468.    * PrintGlobals ();
  469.    */
  470.   strofs = (strofs + 3) & ~3;
  471.  
  472.   mprintf("%6i strofs\n", strofs);
  473.   mprintf("%6i numstatements\n", numstatements);
  474.   mprintf("%6i numfunctions\n", numfunctions);
  475.   mprintf("%6i numglobaldefs\n", numglobaldefs);
  476.   mprintf("%6i numfielddefs\n", numfielddefs);
  477.   mprintf("%6i numpr_globals\n", numpr_globals);
  478.  
  479.   if ((h = __open(destfile, H_READWRITE_BINARY_OLD)) > 0) {
  480.     __write(h, &progs, sizeof(progs));
  481.  
  482.     progs.ofs_strings = __ltell(h);
  483.     progs.numstrings = strofs;
  484.     __write(h, strings, strofs);
  485.  
  486.     progs.ofs_statements = __ltell(h);
  487.     progs.numstatements = numstatements;
  488.     for (i = 0; i < numstatements; i++) {
  489.       statements[i].op = LittleShort(statements[i].op);
  490.       statements[i].a = LittleShort(statements[i].a);
  491.       statements[i].b = LittleShort(statements[i].b);
  492.       statements[i].c = LittleShort(statements[i].c);
  493.     }
  494.     __write(h, statements, numstatements * sizeof(dstatement_t));
  495.  
  496.     progs.ofs_functions = __ltell(h);
  497.     progs.numfunctions = numfunctions;
  498.     for (i = 0; i < numfunctions; i++) {
  499.       functions[i].first_statement = LittleLong(functions[i].first_statement);
  500.       functions[i].parm_start = LittleLong(functions[i].parm_start);
  501.       functions[i].s_name = LittleLong(functions[i].s_name);
  502.       functions[i].s_file = LittleLong(functions[i].s_file);
  503.       functions[i].numparms = LittleLong(functions[i].numparms);
  504.       functions[i].locals = LittleLong(functions[i].locals);
  505.     }
  506.     __write(h, functions, numfunctions * sizeof(dfunction_t));
  507.  
  508.     progs.ofs_globaldefs = __ltell(h);
  509.     progs.numglobaldefs = numglobaldefs;
  510.     for (i = 0; i < numglobaldefs; i++) {
  511.       globals[i].type = LittleShort(globals[i].type);
  512.       globals[i].ofs = LittleShort(globals[i].ofs);
  513.       globals[i].s_name = LittleLong(globals[i].s_name);
  514.     }
  515.     __write(h, globals, numglobaldefs * sizeof(ddef_t));
  516.  
  517.     progs.ofs_fielddefs = __ltell(h);
  518.     progs.numfielddefs = numfielddefs;
  519.     for (i = 0; i < numfielddefs; i++) {
  520.       fields[i].type = LittleShort(fields[i].type);
  521.       fields[i].ofs = LittleShort(fields[i].ofs);
  522.       fields[i].s_name = LittleLong(fields[i].s_name);
  523.     }
  524.     __write(h, fields, numfielddefs * sizeof(ddef_t));
  525.  
  526.     progs.ofs_globals = __ltell(h);
  527.     progs.numglobals = numpr_globals;
  528.     for (i = 0; i < numpr_globals; i++)
  529.       ((int *)pr_globals)[i] = LittleLong(((int *)pr_globals)[i]);
  530.     __write(h, pr_globals, numpr_globals * 4);
  531.  
  532.     mprintf("%6i TOTAL SIZE\n", (int)__ltell(h));
  533.  
  534.     progs.entityfields = pr.size_fields;
  535.     progs.version = PROG_VERSION;
  536.     progs.crc = crc;
  537.  
  538.     /* unsigned char swap the header and write it out */
  539.     for (i = 0; i < sizeof(progs) / 4; i++)
  540.       ((int *)&progs)[i] = LittleLong(((int *)&progs)[i]);
  541.     __lseek(h, 0, SEEK_SET);
  542.     __write(h, &progs, sizeof(progs));
  543.  
  544.     __close(h);
  545.   }
  546. }
  547.  
  548. bool ReadData(register HANDLE srcFile)
  549. {
  550.   dprograms_t progs;
  551.   int i;
  552.   bool retval = FALSE;
  553.  
  554.   while (1) {
  555.     if (__read(srcFile, &progs, sizeof(progs)) != sizeof(progs))
  556.       break;
  557.  
  558.     __lseek(srcFile, LittleLong(progs.ofs_strings), SEEK_SET);
  559.     strofs = LittleLong(progs.numstrings);
  560.     if (!(strings = (char *)kmalloc(strofs)))
  561.       break;
  562.     if (__read(srcFile, strings, strofs) != strofs)
  563.       break;
  564.  
  565.     __lseek(srcFile, LittleLong(progs.ofs_statements), SEEK_SET);
  566.     numstatements = LittleLong(progs.numstatements);
  567.     if (!(statements = (dstatement_t *) kmalloc(numstatements * sizeof(dstatement_t))))
  568.       break;
  569.     if (!(statement_linenums = (int *)kmalloc(numstatements * sizeof(int))))
  570.         break;
  571.  
  572.     if (__read(srcFile, statements, numstatements * sizeof(dstatement_t)) != (numstatements * sizeof(dstatement_t)))
  573.       break;
  574.     for (i = 0; i < numstatements; i++) {
  575.       statements[i].op = LittleShort(statements[i].op);
  576.       statements[i].a = LittleShort(statements[i].a);
  577.       statements[i].b = LittleShort(statements[i].b);
  578.       statements[i].c = LittleShort(statements[i].c);
  579.     }
  580.  
  581.     __lseek(srcFile, LittleLong(progs.ofs_functions), SEEK_SET);
  582.     numfunctions = LittleLong(progs.numfunctions);
  583.     if (!(functions = (dfunction_t *) kmalloc(numfunctions * sizeof(dfunction_t))))
  584.       break;
  585.     if (__read(srcFile, functions, numfunctions * sizeof(dfunction_t)) != (numfunctions * sizeof(dfunction_t)))
  586.       break;
  587.     for (i = 0; i < numfunctions; i++) {
  588.       functions[i].first_statement = LittleLong(functions[i].first_statement);
  589.       functions[i].parm_start = LittleLong(functions[i].parm_start);
  590.       functions[i].locals = LittleLong(functions[i].locals);
  591.       functions[i].s_name = LittleLong(functions[i].s_name);
  592.       functions[i].s_file = LittleLong(functions[i].s_file);
  593.       functions[i].numparms = LittleLong(functions[i].numparms);
  594.     }
  595.  
  596.     __lseek(srcFile, LittleLong(progs.ofs_globaldefs), SEEK_SET);
  597.     numglobaldefs = LittleLong(progs.numglobaldefs);
  598.     if (!(globals = (ddef_t *) kmalloc(numglobaldefs * sizeof(ddef_t))))
  599.       break;
  600.     if (__read(srcFile, globals, numglobaldefs * sizeof(ddef_t)) != (numglobaldefs * sizeof(ddef_t)))
  601.       break;
  602.     for (i = 0; i < numglobaldefs; i++) {
  603.       globals[i].type = LittleShort(globals[i].type);
  604.       globals[i].ofs = LittleShort(globals[i].ofs);
  605.       globals[i].s_name = LittleLong(globals[i].s_name);
  606.     }
  607.  
  608.     __lseek(srcFile, LittleLong(progs.ofs_fielddefs), SEEK_SET);
  609.     numfielddefs = LittleLong(progs.numfielddefs);
  610.     if (!(fields = (ddef_t *) kmalloc(numfielddefs * sizeof(ddef_t))))
  611.       break;
  612.     if (__read(srcFile, fields, numfielddefs * sizeof(ddef_t)) != (numfielddefs * sizeof(ddef_t)))
  613.       break;
  614.     for (i = 0; i < numfielddefs; i++) {
  615.       fields[i].type = LittleShort(fields[i].type);
  616.       fields[i].ofs = LittleShort(fields[i].ofs);
  617.       fields[i].s_name = LittleLong(fields[i].s_name);
  618.     }
  619.  
  620.     __lseek(srcFile, LittleLong(progs.ofs_globals), SEEK_SET);
  621.     numpr_globals = LittleLong(progs.numglobals);
  622.     if (!(pr_globals = (float *)kmalloc(numpr_globals * sizeof(float))))
  623.         break;
  624.  
  625.     if (__read(srcFile, pr_globals, numpr_globals * 4) != (numpr_globals * 4))
  626.       break;
  627.     for (i = 0; i < numpr_globals; i++)
  628.       ((int *)pr_globals)[i] = LittleLong(((int *)pr_globals)[i]);
  629.  
  630.     printf("total size is %6i\n", (int)__ltell(srcFile));
  631.     printf("version code is %i\n", LittleLong(progs.version));
  632.     printf("crc is %i\n", LittleLong(progs.crc));
  633.     printf("%6i strofs\n", strofs);
  634.     printf("%6i numstatements\n", numstatements);
  635.     printf("%6i numfunctions\n", numfunctions);
  636.     printf("%6i numglobaldefs\n", numglobaldefs);
  637.     printf("%6i numfielddefs\n", numfielddefs);
  638.     printf("%6i numpr_globals\n", numpr_globals);
  639.     printf("--------------------------\n");
  640.     retval = TRUE;
  641.     break;
  642.   }
  643.  
  644.   return retval;
  645. }
  646.  
  647. bool ShowData(register HANDLE srcFile)
  648. {
  649.   dprograms_t progs;
  650.  
  651.   if (__read(srcFile, &progs, sizeof(progs)) == sizeof(progs)) {
  652.     strofs = LittleLong(progs.numstrings);
  653.     numstatements = LittleLong(progs.numstatements);
  654.     numfunctions = LittleLong(progs.numfunctions);
  655.     numglobaldefs = LittleLong(progs.numglobaldefs);
  656.     numfielddefs = LittleLong(progs.numfielddefs);
  657.     numpr_globals = LittleLong(progs.numglobals);
  658.  
  659.     __lseek(srcFile, 0, SEEK_END);
  660.     printf("total size is %6i\n", (int)__ltell(srcFile));
  661.     printf("version code is %i\n", LittleLong(progs.version));
  662.     printf("crc is %i\n", LittleLong(progs.crc));
  663.     printf("%6i strofs\n", strofs);
  664.     printf("%6i numstatements\n", numstatements);
  665.     printf("%6i numfunctions\n", numfunctions);
  666.     printf("%6i numglobaldefs\n", numglobaldefs);
  667.     printf("%6i numfielddefs\n", numfielddefs);
  668.     printf("%6i numpr_globals\n", numpr_globals);
  669.     printf("--------------------------\n");
  670.     return TRUE;
  671.   }
  672.   else
  673.     return FALSE;
  674. }
  675.  
  676. /*
  677.  * 
  678.  * ============
  679.  * WriteFiles
  680.  * 
  681.  * Generates files.dat, which contains all of the
  682.  * data files actually used by the game, to be
  683.  * processed by qfiles.exe
  684.  * ============
  685.  */
  686. void WriteFiles(void)
  687. {
  688.   FILE *f;
  689.   int i;
  690.   char filename[NAMELEN_PATH];
  691.  
  692.   sprintf(filename, "%sfiles.dat", sourcedir);
  693.   f = __fopen(filename, "w");
  694.   if (!f)
  695.     eprintf("Couldn't open %s", filename);
  696.   else {
  697.     fprintf(f, "%i\n", numsounds);
  698.     for (i = 0; i < numsounds; i++)
  699.       fprintf(f, "%i %s\n", precache_sounds_block[i], precache_sounds[i]);
  700.  
  701.     fprintf(f, "%i\n", nummodels);
  702.     for (i = 0; i < nummodels; i++)
  703.       fprintf(f, "%i %s\n", precache_models_block[i], precache_models[i]);
  704.  
  705.     fprintf(f, "%i\n", numfiles);
  706.     for (i = 0; i < numfiles; i++)
  707.       fprintf(f, "%i %s\n", precache_files_block[i], precache_files[i]);
  708.  
  709.     __fclose(f);
  710.   }
  711. }
  712.  
  713. /*=========================================================================== */
  714.  
  715. /*
  716.  * ============
  717.  * PR_ParseError
  718.  * 
  719.  * Aborts the current file load
  720.  * ============
  721.  */
  722. void PR_ParseError(register char *error,...)
  723. {
  724.   va_list argptr;
  725.   char string[1024];
  726.  
  727.   va_start(argptr, error);
  728.   vsprintf(string, error, argptr);
  729.   va_end(argptr);
  730.  
  731.   mprintf("%s:%i:%s\n", strings + s_file, pr_source_line, string);
  732.  
  733.   longjmp(pr_parse_abort, 1);
  734. }
  735.  
  736. /*
  737.  * ==============
  738.  * PR_PrintNextLine
  739.  * ==============
  740.  */
  741. void PR_PrintNextLine(void)
  742. {
  743.   char *t;
  744.  
  745.   mprintf("%3i:", pr_source_line);
  746.   for (t = pr_line_start; *t && *t != '\n'; t++)
  747.     mprintf("%c", *t);
  748.   mprintf("\n");
  749. }
  750.  
  751. /*
  752.  * ==============
  753.  * PR_NewLine
  754.  * 
  755.  * Call at start of file and when *pr_file_p == '\n'
  756.  * ==============
  757.  */
  758. void PR_NewLine(void)
  759. {
  760.   bool m;
  761.  
  762.   if (*pr_file_p == '\n') {
  763.     pr_file_p++;
  764.     m = TRUE;
  765.   }
  766.   else
  767.     m = FALSE;
  768.  
  769.   pr_source_line++;
  770.   pr_line_start = pr_file_p;
  771.  
  772.   /*
  773.    * if (pr_dumpasm)
  774.    * PR_PrintNextLine ();
  775.    */
  776.   if (m)
  777.     pr_file_p--;
  778. }
  779.  
  780. /*
  781.  * ==============
  782.  * PR_LexString
  783.  * 
  784.  * Parses a quoted string
  785.  * ==============
  786.  */
  787. void PR_LexString(void)
  788. {
  789.   int c;
  790.   int len;
  791.  
  792.   len = 0;
  793.   pr_file_p++;
  794.   do {
  795.     c = *pr_file_p++;
  796.     if (!c)
  797.       PR_ParseError("EOF inside quote");
  798.     if (c == '\n')
  799.       PR_ParseError("newline inside quote");
  800.     if (c == '\\') {                        /* escape char */
  801.       c = *pr_file_p++;
  802.       if (!c)
  803.     PR_ParseError("EOF inside quote");
  804.       if (c == 'n')
  805.     c = '\n';
  806.       else if (c == '"')
  807.     c = '"';
  808.       else
  809.     PR_ParseError("Unknown escape char");
  810.     }
  811.     else if (c == '\"') {
  812.       pr_token[len] = 0;
  813.       pr_token_type = tt_immediate;
  814.       pr_immediate_type = &type_string;
  815.       __strcpy(pr_immediate_string, pr_token);
  816.       return;
  817.     }
  818.     pr_token[len] = c;
  819.     len++;
  820.   } while (1);
  821. }
  822.  
  823. /*
  824.  * ==============
  825.  * PR_LexNumber
  826.  * ==============
  827.  */
  828. float PR_LexNumber(void)
  829. {
  830.   int c;
  831.   int len;
  832.  
  833.   len = 0;
  834.   c = *pr_file_p;
  835.   do {
  836.     pr_token[len] = c;
  837.     len++;
  838.     pr_file_p++;
  839.     c = *pr_file_p;
  840.   } while ((c >= '0' && c <= '9') || c == '.');
  841.   pr_token[len] = 0;
  842.   return atof(pr_token);
  843. }
  844.  
  845. /*
  846.  * ==============
  847.  * PR_LexWhitespace
  848.  * ==============
  849.  */
  850. void PR_LexWhitespace(void)
  851. {
  852.   int c;
  853.  
  854.   while (1) {
  855.     /* skip whitespace */
  856.     while ((c = *pr_file_p) <= ' ') {
  857.       if (c == '\n')
  858.     PR_NewLine();
  859.       if (c == 0)
  860.     return;                            /* end of file */
  861.  
  862.       pr_file_p++;
  863.     }
  864.  
  865.     /* skip // comments */
  866.     if (c == '/' && pr_file_p[1] == '/') {
  867.       while (*pr_file_p && *pr_file_p != '\n')
  868.     pr_file_p++;
  869.       PR_NewLine();
  870.       pr_file_p++;
  871.       continue;
  872.     }
  873.  
  874.     /* skip * * comments */
  875.     if (c == '/' && pr_file_p[1] == '*') {
  876.       do {
  877.     pr_file_p++;
  878.     if (pr_file_p[0] == '\n')
  879.       PR_NewLine();
  880.     if (pr_file_p[1] == 0)
  881.       return;
  882.       } while (pr_file_p[-1] != '*' || pr_file_p[0] != '/');
  883.       pr_file_p++;
  884.       continue;
  885.     }
  886.     break;                            /* a real character has been found */
  887.  
  888.   }
  889. }
  890.  
  891. /*
  892.  * ==============
  893.  * PR_LexVector
  894.  * 
  895.  * Parses a single quoted vector
  896.  * ==============
  897.  */
  898. void PR_LexVector(void)
  899. {
  900.   int i;
  901.  
  902.   pr_file_p++;
  903.   pr_token_type = tt_immediate;
  904.   pr_immediate_type = &type_vector;
  905.   for (i = 0; i < 3; i++) {
  906.     pr_immediate.vector[i] = PR_LexNumber();
  907.     PR_LexWhitespace();
  908.   }
  909.   if (*pr_file_p != '\'')
  910.     PR_ParseError("Bad vector");
  911.   pr_file_p++;
  912. }
  913.  
  914. /*
  915.  * ==============
  916.  * PR_LexName
  917.  * 
  918.  * Parses an identifier
  919.  * ==============
  920.  */
  921. void PR_LexName(void)
  922. {
  923.   int c;
  924.   int len;
  925.  
  926.   len = 0;
  927.   c = *pr_file_p;
  928.   do {
  929.     pr_token[len] = c;
  930.     len++;
  931.     pr_file_p++;
  932.     c = *pr_file_p;
  933.   } while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9'));
  934.   pr_token[len] = 0;
  935.   pr_token_type = tt_name;
  936. }
  937.  
  938. /*
  939.  * ==============
  940.  * PR_LexPunctuation
  941.  * ==============
  942.  */
  943. void PR_LexPunctuation(void)
  944. {
  945.   int i;
  946.   int len;
  947.   char *p;
  948.  
  949.   pr_token_type = tt_punct;
  950.  
  951.   for (i = 0; (p = pr_punctuation[i]) != NULL; i++) {
  952.     len = __strlen(p);
  953.     if (!__strncmp(p, pr_file_p, len)) {
  954.       __strcpy(pr_token, p);
  955.       if (p[0] == '{')
  956.     pr_bracelevel++;
  957.       else if (p[0] == '}')
  958.     pr_bracelevel--;
  959.       pr_file_p += len;
  960.       return;
  961.     }
  962.   }
  963.  
  964.   PR_ParseError("Unknown punctuation");
  965. }
  966.  
  967. void PR_ClearGrabMacros(void)
  968. {
  969.   pr_nummacros = 0;
  970. }
  971.  
  972. void PR_FindMacro(void)
  973. {
  974.   int i;
  975.  
  976.   for (i = 0; i < pr_nummacros; i++)
  977.     if (!__strcmp(pr_token, pr_framemacros[i])) {
  978.       sprintf(pr_token, "%d", i);
  979.       pr_token_type = tt_immediate;
  980.       pr_immediate_type = &type_float;
  981.       pr_immediate._float = i;
  982.       return;
  983.     }
  984.   PR_ParseError("Unknown frame macro $%s", pr_token);
  985. }
  986.  
  987. /* just parses text, returning FALSE if an eol is reached */
  988. bool PR_SimpleGetToken(void)
  989. {
  990.   int c;
  991.   int i;
  992.  
  993.   /* skip whitespace */
  994.   while ((c = *pr_file_p) <= ' ') {
  995.     if (c == '\n' || c == 0)
  996.       return FALSE;
  997.     pr_file_p++;
  998.   }
  999.  
  1000.   i = 0;
  1001.   while ((c = *pr_file_p) > ' ' && c != ',' && c != ';') {
  1002.     pr_token[i] = c;
  1003.     i++;
  1004.     pr_file_p++;
  1005.   }
  1006.   pr_token[i] = 0;
  1007.   return TRUE;
  1008. }
  1009.  
  1010. void PR_ParseFrame(void)
  1011. {
  1012.   while (PR_SimpleGetToken()) {
  1013.     __strcpy(pr_framemacros[pr_nummacros], pr_token);
  1014.     pr_nummacros++;
  1015.   }
  1016. }
  1017.  
  1018. /*
  1019.  * ==============
  1020.  * PR_Lex
  1021.  * 
  1022.  * Sets pr_token, pr_token_type, and possibly pr_immediate and pr_immediate_type
  1023.  * ==============
  1024.  */
  1025. void PR_LexGrab(void);
  1026. void PR_Lex(void)
  1027. {
  1028.   int c;
  1029.  
  1030.   pr_token[0] = 0;
  1031.  
  1032.   if (!pr_file_p) {
  1033.     pr_token_type = tt_eof;
  1034.     return;
  1035.   }
  1036.  
  1037.   PR_LexWhitespace();
  1038.  
  1039.   c = *pr_file_p;
  1040.  
  1041.   if (!c) {
  1042.     pr_token_type = tt_eof;
  1043.     return;
  1044.   }
  1045.  
  1046.   /* handle quoted strings as a unit */
  1047.   if (c == '\"') {
  1048.     PR_LexString();
  1049.     return;
  1050.   }
  1051.  
  1052.   /* handle quoted vectors as a unit */
  1053.   if (c == '\'') {
  1054.     PR_LexVector();
  1055.     return;
  1056.   }
  1057.  
  1058.   /* if the first character is a valid identifier, parse until a non-id */
  1059.   /* character is reached */
  1060.   if ((c >= '0' && c <= '9') || (c == '-' && pr_file_p[1] >= '0' && pr_file_p[1] <= '9')) {
  1061.     pr_token_type = tt_immediate;
  1062.     pr_immediate_type = &type_float;
  1063.     pr_immediate._float = PR_LexNumber();
  1064.     return;
  1065.   }
  1066.  
  1067.   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
  1068.     PR_LexName();
  1069.     return;
  1070.   }
  1071.  
  1072.   if (c == '$') {
  1073.     PR_LexGrab();
  1074.     return;
  1075.   }
  1076.  
  1077.   /* parse symbol strings until a non-symbol is found */
  1078.   PR_LexPunctuation();
  1079. }
  1080.  
  1081. /*
  1082.  * ==============
  1083.  * PR_LexGrab
  1084.  * 
  1085.  * Deals with counting sequence numbers and replacing frame macros
  1086.  * ==============
  1087.  */
  1088. void PR_LexGrab(void)
  1089. {
  1090.   pr_file_p++;                            /* skip the $ */
  1091.  
  1092.   if (!PR_SimpleGetToken())
  1093.     PR_ParseError("hanging $");
  1094.  
  1095.   /* check for $frame */
  1096.   if (!__strcmp(pr_token, "frame")) {
  1097.     PR_ParseFrame();
  1098.     PR_Lex();
  1099.   }
  1100.   /* ignore other known $commands */
  1101.   else if (!__strcmp(pr_token, "cd")
  1102.        || !__strcmp(pr_token, "origin")
  1103.        || !__strcmp(pr_token, "base")
  1104.        || !__strcmp(pr_token, "flags")
  1105.        || !__strcmp(pr_token, "scale")
  1106.        || !__strcmp(pr_token, "skin")) {            /* skip to end of line */
  1107.  
  1108.     while (PR_SimpleGetToken());
  1109.     PR_Lex();
  1110.   }
  1111.   /* look for a frame name macro */
  1112.   else
  1113.     PR_FindMacro();
  1114. }
  1115.  
  1116. /*
  1117.  * =============
  1118.  * PR_Expect
  1119.  * 
  1120.  * Issues an error if the current token isn't equal to string
  1121.  * Gets the next token
  1122.  * =============
  1123.  */
  1124. void PR_Expect(register char *string)
  1125. {
  1126.   if (__strcmp(string, pr_token))
  1127.     PR_ParseError("expected %s, found %s", string, pr_token);
  1128.   PR_Lex();
  1129. }
  1130.  
  1131. /*
  1132.  * =============
  1133.  * PR_Check
  1134.  * 
  1135.  * Returns TRUE and gets the next token if the current token equals string
  1136.  * Returns FALSE and does nothing otherwise
  1137.  * =============
  1138.  */
  1139. bool PR_Check(register char *string)
  1140. {
  1141.   if (__strcmp(string, pr_token))
  1142.     return FALSE;
  1143.  
  1144.   PR_Lex();
  1145.   return TRUE;
  1146. }
  1147.  
  1148. /*
  1149.  * ============
  1150.  * PR_ParseName
  1151.  * 
  1152.  * Checks to see if the current token is a valid name
  1153.  * ============
  1154.  */
  1155. char *PR_ParseName(void)
  1156. {
  1157.   static char ident[MAX_NAME];
  1158.  
  1159.   if (pr_token_type != tt_name)
  1160.     PR_ParseError("not a name");
  1161.   if (__strlen(pr_token) >= MAX_NAME - 1)
  1162.     PR_ParseError("name too long");
  1163.   __strcpy(ident, pr_token);
  1164.   PR_Lex();
  1165.  
  1166.   return ident;
  1167. }
  1168.  
  1169. /*
  1170.  * ============
  1171.  * PR_FindType
  1172.  * 
  1173.  * Returns a preexisting complex type that matches the parm, or allocates
  1174.  * a new one and copies it out.
  1175.  * ============
  1176.  */
  1177. type_t *PR_FindType(register type_t * type)
  1178. {
  1179.   def_t *def;
  1180.   type_t *check;
  1181.   int i;
  1182.  
  1183.   for (check = pr.types; check; check = check->next) {
  1184.     if (check->type != type->type
  1185.     || check->aux_type != type->aux_type
  1186.     || check->num_parms != type->num_parms)
  1187.       continue;
  1188.  
  1189.     for (i = 0; i < type->num_parms; i++)
  1190.       if (check->parm_types[i] != type->parm_types[i])
  1191.     break;
  1192.  
  1193.     if (i == type->num_parms)
  1194.       return check;
  1195.   }
  1196.  
  1197.   /* allocate a new one */
  1198.   check = (type_t *) kmalloc(sizeof(*check));
  1199.   *check = *type;
  1200.   check->next = pr.types;
  1201.   pr.types = check;
  1202.  
  1203.   /* allocate a generic def for the type, so fields can reference it */
  1204.   def = (def_t *) kmalloc(sizeof(def_t));
  1205.   def->name = "COMPLEX TYPE";
  1206.   def->type = check;
  1207.   check->def = def;
  1208.   return check;
  1209. }
  1210.  
  1211. /*
  1212.  * ============
  1213.  * PR_SkipToSemicolon
  1214.  * 
  1215.  * For error recovery, also pops out of nested braces
  1216.  * ============
  1217.  */
  1218. void PR_SkipToSemicolon(void)
  1219. {
  1220.   do {
  1221.     if (!pr_bracelevel && PR_Check(";"))
  1222.       return;
  1223.     PR_Lex();
  1224.   } while (pr_token[0]);                    /* eof will return a null token */
  1225.  
  1226. }
  1227.  
  1228. /*
  1229.  * ============
  1230.  * PR_ParseType
  1231.  * 
  1232.  * Parses a variable type, including field and functions types
  1233.  * ============
  1234.  */
  1235. type_t *PR_ParseType(void)
  1236. {
  1237.   type_t new;
  1238.   type_t *type;
  1239.   char *name;
  1240.  
  1241.   if (PR_Check(".")) {
  1242.     __bzero(&new, sizeof(new));
  1243.     new.type = ev_field;
  1244.     new.aux_type = PR_ParseType();
  1245.     return PR_FindType(&new);
  1246.   }
  1247.  
  1248.   if (!__strcmp(pr_token, "float"))
  1249.     type = &type_float;
  1250.   else if (!__strcmp(pr_token, "vector"))
  1251.     type = &type_vector;
  1252.   else if (!__strcmp(pr_token, "float"))
  1253.     type = &type_float;
  1254.   else if (!__strcmp(pr_token, "entity"))
  1255.     type = &type_entity;
  1256.   else if (!__strcmp(pr_token, "string"))
  1257.     type = &type_string;
  1258.   else if (!__strcmp(pr_token, "void"))
  1259.     type = &type_void;
  1260.   else {
  1261.     PR_ParseError("\"%s\" is not a type", pr_token);
  1262.     type = &type_float;                        /* shut up compiler warning */
  1263.   }
  1264.   PR_Lex();
  1265.  
  1266.   if (!PR_Check("("))
  1267.     return type;
  1268.  
  1269.   /* function type */
  1270.   __bzero(&new, sizeof(new));
  1271.   new.type = ev_function;
  1272.   new.aux_type = type;                        /* return type */
  1273.  
  1274.   new.num_parms = 0;
  1275.   if (!PR_Check(")")) {
  1276.     if (PR_Check("..."))
  1277.       new.num_parms = -1;                    /* variable args */
  1278.     else
  1279.       do {
  1280.     type = PR_ParseType();
  1281.     name = PR_ParseName();
  1282.     __strcpy(pr_parm_names[new.num_parms], name);
  1283.     new.parm_types[new.num_parms] = type;
  1284.     new.num_parms++;
  1285.       } while (PR_Check(","));
  1286.  
  1287.     PR_Expect(")");
  1288.   }
  1289.  
  1290.   return PR_FindType(&new);
  1291. }
  1292. /*
  1293.  * ============
  1294.  * PR_Statement
  1295.  * 
  1296.  * Emits a primitive statement, returning the var it places it's value in
  1297.  * ============
  1298.  */
  1299. def_t *PR_Statement(register opcode_t * op, register def_t * var_a, register def_t * var_b)
  1300. {
  1301.   dstatement_t *statement;
  1302.   def_t *var_c;
  1303.  
  1304.   statement = &statements[numstatements];
  1305.   numstatements++;
  1306.  
  1307.   statement_linenums[statement - statements] = pr_source_line;
  1308.   statement->op = op - pr_opcodes;
  1309.   statement->a = var_a ? var_a->ofs : 0;
  1310.   statement->b = var_b ? var_b->ofs : 0;
  1311.   if (op->type_c == &def_void || op->right_associative) {
  1312.     var_c = NULL;
  1313.     statement->c = 0;                        /* ifs, gotos, and assignments */
  1314.     /* don't need vars allocated */
  1315.  
  1316.   }
  1317.   else {                            /* allocate result space */
  1318.  
  1319.     var_c = (def_t *) kmalloc(sizeof(def_t));
  1320. /*__bzero(var_c, sizeof(def_t)); */
  1321.     var_c->ofs = numpr_globals;
  1322.     var_c->type = op->type_c->type;
  1323.  
  1324.     statement->c = numpr_globals;
  1325.     numpr_globals += type_size[op->type_c->type->type];
  1326.   }
  1327.  
  1328.   if (op->right_associative)
  1329.     return var_a;
  1330.   return var_c;
  1331. }
  1332.  
  1333. /*
  1334.  * ============
  1335.  * PR_ParseImmediate
  1336.  * 
  1337.  * Looks for a preexisting constant
  1338.  * ============
  1339.  */
  1340. #if 0
  1341. def_t *PR_ParseImmediate(void)
  1342. {
  1343.   def_t *cn;
  1344.  
  1345.   /* check for a constant with the same value */
  1346.   for (cn = pr.def_head.next; cn; cn = cn->next) {
  1347.     if (!cn->initialized)
  1348.       continue;
  1349.     if (cn->type != pr_immediate_type)
  1350.       continue;
  1351.     if (pr_immediate_type == &type_string) {
  1352.       if (!__strcmp(G_STRING(cn->ofs), pr_immediate_string)) {
  1353.     PR_Lex();
  1354.     return cn;
  1355.       }
  1356.     }
  1357.     else if (pr_immediate_type == &type_float) {
  1358.       if (G_FLOAT(cn->ofs) == pr_immediate._float) {
  1359.     PR_Lex();
  1360.     return cn;
  1361.       }
  1362.     }
  1363.     else if (pr_immediate_type == &type_vector) {
  1364.       if ((G_FLOAT(cn->ofs) == pr_immediate.vector[0])
  1365.       && (G_FLOAT(cn->ofs + 1) == pr_immediate.vector[1])
  1366.       && (G_FLOAT(cn->ofs + 2) == pr_immediate.vector[2])) {
  1367.     PR_Lex();
  1368.     return cn;
  1369.       }
  1370.     }
  1371.     else
  1372.       PR_ParseError("weird immediate type");
  1373.   }
  1374.  
  1375.   /* allocate a new one */
  1376.   cn = (def_t *) kmalloc(sizeof(def_t));
  1377.   cn->next = NULL;
  1378.  
  1379.   pr.def_tail->next = cn;
  1380.  
  1381.   pr.def_tail = cn;
  1382.  
  1383.   cn->search_next = pr.search;
  1384.  
  1385.   pr.search = cn;
  1386.  
  1387.   cn->type = pr_immediate_type;
  1388.   cn->name = "IMMEDIATE";
  1389.   cn->initialized = 1;
  1390.   cn->scope = NULL;                        /* always share immediates */
  1391.  
  1392.   /* copy the immediate to the global area */
  1393.   cn->ofs = numpr_globals;
  1394.   pr_global_defs[cn->ofs] = cn;
  1395.   numpr_globals += type_size[pr_immediate_type->type];
  1396.   if (pr_immediate_type == &type_string)
  1397.     pr_immediate.string = CopyString(pr_immediate_string);
  1398.  
  1399.   memcpy(pr_globals + cn->ofs, &pr_immediate, 4 * type_size[pr_immediate_type->type]);
  1400.  
  1401.   PR_Lex();
  1402.  
  1403.   return cn;
  1404. }
  1405. #else
  1406. def_t *PR_ParseImmediate(void)
  1407. {
  1408. #undef cacheSize
  1409. #undef cacheMask
  1410. #define cacheSize  32
  1411. #define cacheMask  (cacheSize - 1)
  1412.   static def_t *stringCache[cacheSize];
  1413.   static int stringTop = 0;
  1414.   static def_t *floatCache[cacheSize];
  1415.   static int floatTop = 0;
  1416.   static def_t *vectorCache[cacheSize];
  1417.   static int vectorTop = 0;
  1418.   int sub;
  1419.   def_t *cn;
  1420.  
  1421.   if (pr_immediate_type == &type_string) {
  1422.     /* See if constant is in cache. */
  1423.     sub = stringTop;
  1424.     do {
  1425.       cn = stringCache[sub];
  1426.       if (!cn)
  1427.     break;
  1428.       if (!__strcmp(G_STRING(cn->ofs), pr_immediate_string)) {
  1429.     PR_Lex();
  1430.     stringCache[sub] = stringCache[stringTop];
  1431.     stringCache[stringTop] = cn;
  1432.     return cn;
  1433.       }
  1434.       sub = (sub - 1) & cacheMask;
  1435.     }
  1436.     while (sub != stringTop);
  1437.  
  1438.     /* See if constant is in main list. */
  1439.     for (cn = pr.def_tail; cn; cn = cn->prev) {
  1440.       if (!cn->initialized || cn->type != pr_immediate_type)
  1441.     continue;
  1442.       if (!__strcmp(G_STRING(cn->ofs), pr_immediate_string)) {
  1443.     PR_Lex();
  1444.     stringTop = (stringTop + 1) & cacheMask;
  1445.     stringCache[stringTop] = cn;
  1446.     return cn;
  1447.       }
  1448.     }
  1449.   }
  1450.   else if (pr_immediate_type == &type_float) {
  1451.     /* See if constant is in cache. */
  1452.     sub = floatTop;
  1453.     do {
  1454.       cn = floatCache[sub];
  1455.       if (!cn)
  1456.     break;
  1457.       if (G_FLOAT(cn->ofs) == pr_immediate._float) {
  1458.     PR_Lex();
  1459.     floatCache[sub] = floatCache[floatTop];
  1460.     floatCache[floatTop] = cn;
  1461.     return cn;
  1462.       }
  1463.       sub = (sub - 1) & cacheMask;
  1464.     }
  1465.     while (sub != floatTop);
  1466.  
  1467.     /* See if constant is in main list. */
  1468.     for (cn = pr.def_tail; cn; cn = cn->prev) {
  1469.       if (!cn->initialized || cn->type != pr_immediate_type)
  1470.     continue;
  1471.       if (G_FLOAT(cn->ofs) == pr_immediate._float) {
  1472.     PR_Lex();
  1473.     floatTop = (floatTop + 1) & cacheMask;
  1474.     floatCache[floatTop] = cn;
  1475.     return cn;
  1476.       }
  1477.     }
  1478.   }
  1479.   else if (pr_immediate_type == &type_vector) {
  1480.     /* See if constant is in cache. */
  1481.     sub = vectorTop;
  1482.     do {
  1483.       cn = vectorCache[sub];
  1484.       if (!cn)
  1485.     break;
  1486.       if ((G_FLOAT(cn->ofs) == pr_immediate.vector[0])
  1487.       && (G_FLOAT(cn->ofs + 1) == pr_immediate.vector[1])
  1488.       && (G_FLOAT(cn->ofs + 2) == pr_immediate.vector[2])) {
  1489.     PR_Lex();
  1490.     vectorCache[sub] = vectorCache[vectorTop];
  1491.     vectorCache[vectorTop] = cn;
  1492.     return cn;
  1493.       }
  1494.       sub = (sub - 1) & cacheMask;
  1495.     }
  1496.     while (sub != vectorTop);
  1497.  
  1498.     /* See if constant is in main list. */
  1499.     for (cn = pr.def_tail; cn; cn = cn->prev) {
  1500.       if (!cn->initialized || cn->type != pr_immediate_type)
  1501.     continue;
  1502.       if ((G_FLOAT(cn->ofs) == pr_immediate.vector[0])
  1503.       && (G_FLOAT(cn->ofs + 1) == pr_immediate.vector[1])
  1504.       && (G_FLOAT(cn->ofs + 2) == pr_immediate.vector[2])) {
  1505.     PR_Lex();
  1506.     vectorTop = (vectorTop + 1) & cacheMask;
  1507.     vectorCache[vectorTop] = cn;
  1508.     return cn;
  1509.       }
  1510.     }
  1511.   }
  1512.   else {
  1513.     PR_ParseError("weird immediate type");
  1514.   }
  1515.  
  1516.   /* allocate a new one */
  1517.   cn = (def_t *) kmalloc(sizeof(def_t));
  1518.   cn->next = NULL;
  1519.   if (!pr.def_head) {
  1520.     cn->prev = NULL;
  1521.     pr.def_head = pr.def_tail = cn;
  1522.   }
  1523.   else {
  1524.     pr.def_tail->next = cn;
  1525.     cn->prev = pr.def_tail;
  1526.     pr.def_tail = cn;
  1527.   }
  1528.   cn->type = pr_immediate_type;
  1529.   cn->name = "IMMEDIATE";
  1530.   cn->initialized = 1;
  1531.   cn->scope = NULL;                        /* always share immediates */
  1532.  
  1533.   /* Copy the immediate to the global area */
  1534.   cn->ofs = numpr_globals;
  1535.   pr_global_defs[cn->ofs] = cn;
  1536.  
  1537.   /* Put immediate into cache. */
  1538.   if (pr_immediate_type == &type_string) {
  1539.     stringTop = (stringTop + 1) & cacheMask;
  1540.     stringCache[stringTop] = cn;
  1541.   }
  1542.   else if (pr_immediate_type == &type_float) {
  1543.     floatTop = (floatTop + 1) & cacheMask;
  1544.     floatCache[floatTop] = cn;
  1545.   }
  1546.   else {
  1547.     vectorTop = (vectorTop + 1) & cacheMask;
  1548.     vectorCache[vectorTop] = cn;
  1549.   }
  1550.  
  1551.   numpr_globals += type_size[pr_immediate_type->type];
  1552.   if (pr_immediate_type == &type_string)
  1553.     pr_immediate.string = CopyString(pr_immediate_string);
  1554.  
  1555.   __memcpy(pr_globals + cn->ofs, &pr_immediate, 4 * type_size[pr_immediate_type->type]);
  1556.  
  1557.   PR_Lex();
  1558.  
  1559.   return cn;
  1560. }
  1561. #endif
  1562.  
  1563. /*
  1564.  * ============
  1565.  * PR_ParseFunctionCall
  1566.  * ============
  1567.  */
  1568. def_t *PR_ParseFunctionCall(register def_t * func)
  1569. {
  1570.   def_t *e;
  1571.   int arg;
  1572.   type_t *t;
  1573.  
  1574.   t = func->type;
  1575.  
  1576.   if (t->type != ev_function)
  1577.     PR_ParseError("not a function");
  1578.  
  1579.   /* copy the arguments to the global parameter variables */
  1580.   arg = 0;
  1581.   if (!PR_Check(")")) {
  1582.     do {
  1583.       if (t->num_parms != -1 && arg >= t->num_parms)
  1584.     PR_ParseError("too many parameters");
  1585.       e = PR_Expression(TOP_PRIORITY);
  1586.  
  1587.       if (arg == 0 && func->name) {
  1588.     /* save information for model and sound caching */
  1589.     if (!__strncmp(func->name, "precache_sound", 14))
  1590.       PrecacheSound(e, func->name[14]);
  1591.     else if (!__strncmp(func->name, "precache_model", 14))
  1592.       PrecacheModel(e, func->name[14]);
  1593.     else if (!__strncmp(func->name, "precache_file", 13))
  1594.       PrecacheFile(e, func->name[13]);
  1595.       }
  1596.  
  1597.       if (t->num_parms != -1 && (e->type != t->parm_types[arg]))
  1598.     PR_ParseError("type mismatch on parm %i", arg);
  1599.       /* a vector copy will copy everything */
  1600.       def_parms[arg].type = t->parm_types[arg];
  1601.       PR_Statement(&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
  1602.       arg++;
  1603.     } while (PR_Check(","));
  1604.  
  1605.     if (t->num_parms != -1 && arg != t->num_parms)
  1606.       PR_ParseError("too few parameters");
  1607.     PR_Expect(")");
  1608.   }
  1609.   if (arg > 8)
  1610.     PR_ParseError("More than eight parameters");
  1611.  
  1612.   PR_Statement(&pr_opcodes[OP_CALL0 + arg], func, 0);
  1613.  
  1614.   def_ret.type = t->aux_type;
  1615.   return &def_ret;
  1616. }
  1617.  
  1618. /*
  1619.  * ============
  1620.  * PR_GetDef
  1621.  * 
  1622.  * If type is NULL, it will match any type
  1623.  * If allocate is TRUE, a new def will be allocated if it can't be found
  1624.  * ============
  1625.  */
  1626. #if 0
  1627. def_t *PR_GetDef(register type_t * type, register char *name, register def_t * scope, register bool allocate)
  1628. {
  1629.   def_t *def, **old;
  1630.   char element[MAX_NAME];
  1631.  
  1632.   /* see if the name is already in use */
  1633.   old = &pr.search;
  1634.   for (def = *old; def; old = &def->search_next, def = *old)
  1635.     if (!__strcmp(def->name, name)) {
  1636.       if (def->scope && def->scope != scope)
  1637.     continue;                        /* in a different function */
  1638.  
  1639.       if (type && def->type != type)
  1640.     PR_ParseError("Type mismatch on redeclaration of %s", name);
  1641.  
  1642.       /* move to head of list to find fast next time */
  1643.       *old = def->search_next;
  1644.  
  1645.       def->search_next = pr.search;
  1646.  
  1647.       pr.search = def;
  1648.  
  1649.       return def;
  1650.     }
  1651.  
  1652.   if (!allocate)
  1653.     return NULL;
  1654.  
  1655.   /* allocate a new def */
  1656.   def = (def_t *) kmalloc(sizeof(def_t));
  1657.   /*bzero(def, sizeof(*def)); */
  1658.   def->next = NULL;
  1659.   pr.def_tail->next = def;
  1660.  
  1661.   pr.def_tail = def;
  1662.  
  1663.   def->search_next = pr.search;
  1664.  
  1665.   pr.search = def;
  1666.  
  1667.   /*def->name = (char *)kmalloc(__strlen(name) + 1); */
  1668. /*__strcpy(def->name, name); */
  1669.   def->name = smalloc(name);
  1670.   def->type = type;
  1671.  
  1672.   def->scope = scope;
  1673.  
  1674.   def->ofs = numpr_globals;
  1675.   pr_global_defs[numpr_globals] = def;
  1676.  
  1677.   /*
  1678.    * make automatic defs for the vectors elements
  1679.    * .origin can be accessed as .origin_x, .origin_y, and .origin_z
  1680.    */
  1681.   if (type->type == ev_vector) {
  1682.     sprintf(element, "%s_x", name);
  1683.     PR_GetDef(&type_float, element, scope, TRUE);
  1684.  
  1685.     sprintf(element, "%s_y", name);
  1686.     PR_GetDef(&type_float, element, scope, TRUE);
  1687.  
  1688.     sprintf(element, "%s_z", name);
  1689.     PR_GetDef(&type_float, element, scope, TRUE);
  1690.   }
  1691.   else
  1692.     numpr_globals += type_size[type->type];
  1693.  
  1694.   if (type->type == ev_field) {
  1695.     *(int *)&pr_globals[def->ofs] = pr.size_fields;
  1696.  
  1697.     if (type->aux_type->type == ev_vector) {
  1698.       sprintf(element, "%s_x", name);
  1699.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1700.  
  1701.       sprintf(element, "%s_y", name);
  1702.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1703.  
  1704.       sprintf(element, "%s_z", name);
  1705.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1706.     }
  1707.     else
  1708.       pr.size_fields += type_size[type->aux_type->type];
  1709.   }
  1710.  
  1711.   /*      if (pr_dumpasm) */
  1712.   /*              PR_PrintOfs (def->ofs); */
  1713.  
  1714.   return def;
  1715. }
  1716. #else
  1717. def_t *PR_GetDef(register type_t * type, register char *name, register def_t * scope, register bool allocate)
  1718. {
  1719. #undef cacheSize
  1720. #undef cacheMask
  1721. #define cacheSize  128
  1722. #define cacheMask  (cacheSize - 1)
  1723.   static def_t *cache[cacheSize];
  1724.   static int top = 0;
  1725.   def_t *def;
  1726.   int len;
  1727.   char element[MAX_NAME];
  1728.  
  1729.   /* See if name is in cache. */
  1730.   int sub = top;
  1731.  
  1732.   do {
  1733.     def = cache[sub];
  1734.     if (!def)
  1735.       break;
  1736.     if (!def->scope || def->scope == scope) {
  1737.       if (!__strcmp(def->name, name)) {
  1738.     if (type && def->type != type)
  1739.       PR_ParseError(
  1740.              "Type mismatch on redeclaration of %s", name);
  1741.     cache[sub] = cache[top];
  1742.     cache[top] = def;
  1743.     return def;
  1744.       }
  1745.     }
  1746.     sub = (sub - 1) & cacheMask;
  1747.   }
  1748.   while (sub != top);
  1749.  
  1750.   /* See if name is in main list. */
  1751.   for (def = pr.def_tail; def; def = def->prev) {
  1752.     if (!def->scope || def->scope == scope) {
  1753.       if (!__strcmp(def->name, name)) {
  1754.     if (type && def->type != type)
  1755.       PR_ParseError(
  1756.              "Type mismatch on redeclaration of %s", name);
  1757.  
  1758.     /* Put entry in cache. */
  1759.     top = (top + 1) & cacheMask;
  1760.     cache[top] = def;
  1761.     return def;
  1762.       }
  1763.     }
  1764.   }
  1765.  
  1766.   if (!allocate)
  1767.     return NULL;
  1768.  
  1769.   /* allocate a new def */
  1770.   len = __strlen(name) + 1;
  1771.   def = malloc(sizeof(def_t) + len);
  1772.   def->next = NULL;
  1773.   if (!pr.def_head) {
  1774.     def->prev = NULL;
  1775.     pr.def_head = pr.def_tail = def;
  1776.   }
  1777.   else {
  1778.     pr.def_tail->next = def;
  1779.     def->prev = pr.def_tail;
  1780.     pr.def_tail = def;
  1781.   }
  1782.   def->name = (char *)def + sizeof(def_t);
  1783.   memcpy(def->name, name, len);
  1784.   def->type = type;
  1785.   def->initialized = 0;
  1786.   def->scope = scope;
  1787.   def->ofs = numpr_globals;
  1788.   pr_global_defs[numpr_globals] = def;
  1789.  
  1790.   /* Put entry in cache. */
  1791.   top = (top + 1) & cacheMask;
  1792.   cache[top] = def;
  1793.  
  1794.   /*
  1795.    * make automatic defs for the vectors elements
  1796.    * .origin can be accessed as .origin_x, .origin_y, and .origin_z
  1797.    */
  1798.   if (type->type == ev_vector) {
  1799.     sprintf(element, "%s_x", name);
  1800.     PR_GetDef(&type_float, element, scope, TRUE);
  1801.  
  1802.     sprintf(element, "%s_y", name);
  1803.     PR_GetDef(&type_float, element, scope, TRUE);
  1804.  
  1805.     sprintf(element, "%s_z", name);
  1806.     PR_GetDef(&type_float, element, scope, TRUE);
  1807.   }
  1808.   else
  1809.     numpr_globals += type_size[type->type];
  1810.  
  1811.   if (type->type == ev_field) {
  1812.     *(int *)&pr_globals[def->ofs] = pr.size_fields;
  1813.  
  1814.     if (type->aux_type->type == ev_vector) {
  1815.       sprintf(element, "%s_x", name);
  1816.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1817.  
  1818.       sprintf(element, "%s_y", name);
  1819.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1820.  
  1821.       sprintf(element, "%s_z", name);
  1822.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1823.     }
  1824.     else
  1825.       pr.size_fields += type_size[type->aux_type->type];
  1826.   }
  1827.  
  1828.   /*      if (pr_dumpasm) */
  1829.   /*              PR_PrintOfs (def->ofs); */
  1830.  
  1831.   return def;
  1832. }
  1833. #endif
  1834.  
  1835. /*
  1836.  * ============
  1837.  * PR_ParseValue
  1838.  * 
  1839.  * Returns the global ofs for the current token
  1840.  * ============
  1841.  */
  1842. def_t *PR_ParseValue(void)
  1843. {
  1844.   def_t *d;
  1845.   char *name;
  1846.  
  1847.   /* if the token is an immediate, allocate a constant for it */
  1848.   if (pr_token_type == tt_immediate)
  1849.     return PR_ParseImmediate();
  1850.  
  1851.   name = PR_ParseName();
  1852.  
  1853.   /* look through the defs */
  1854.   d = PR_GetDef(NULL, name, pr_scope, FALSE);
  1855.   if (!d)
  1856.     PR_ParseError("Unknown value \"%s\"", name);
  1857.   return d;
  1858. }
  1859.  
  1860. /*
  1861.  * ============
  1862.  * PR_Term
  1863.  * ============
  1864.  */
  1865. def_t *PR_Term(void)
  1866. {
  1867.   def_t *e, *e2;
  1868.   etype_t t;
  1869.  
  1870.   if (PR_Check("!")) {
  1871.     e = PR_Expression(NOT_PRIORITY);
  1872.     t = e->type->type;
  1873.     if (t == ev_float)
  1874.       e2 = PR_Statement(&pr_opcodes[OP_NOT_F], e, 0);
  1875.     else if (t == ev_string)
  1876.       e2 = PR_Statement(&pr_opcodes[OP_NOT_S], e, 0);
  1877.     else if (t == ev_entity)
  1878.       e2 = PR_Statement(&pr_opcodes[OP_NOT_ENT], e, 0);
  1879.     else if (t == ev_vector)
  1880.       e2 = PR_Statement(&pr_opcodes[OP_NOT_V], e, 0);
  1881.     else if (t == ev_function)
  1882.       e2 = PR_Statement(&pr_opcodes[OP_NOT_FNC], e, 0);
  1883.     else {
  1884.       e2 = NULL;                        /* shut up compiler warning; */
  1885.  
  1886.       PR_ParseError("type mismatch for !");
  1887.     }
  1888.     return e2;
  1889.   }
  1890.  
  1891.   if (PR_Check("(")) {
  1892.     e = PR_Expression(TOP_PRIORITY);
  1893.     PR_Expect(")");
  1894.     return e;
  1895.   }
  1896.  
  1897.   return PR_ParseValue();
  1898. }
  1899.  
  1900. /*
  1901.  * ==============
  1902.  * PR_Expression
  1903.  * ==============
  1904.  */
  1905.  
  1906. def_t *PR_Expression(register int priority)
  1907. {
  1908.   opcode_t *op, *oldop;
  1909.   def_t *e, *e2;
  1910.   etype_t type_a, type_b, type_c;
  1911.  
  1912.   if (priority == 0)
  1913.     return PR_Term();
  1914.  
  1915.   e = PR_Expression(priority - 1);
  1916.  
  1917.   while (1) {
  1918.     if (priority == 1 && PR_Check("("))
  1919.       return PR_ParseFunctionCall(e);
  1920.  
  1921.     for (op = pr_opcodes; op->name; op++) {
  1922.       if (op->priority != priority)
  1923.     continue;
  1924.       if (!PR_Check(op->name))
  1925.     continue;
  1926.       if (op->right_associative) {
  1927.     /* if last statement is an indirect, change it to an address of */
  1928.     if ((unsigned)(statements[numstatements - 1].op - OP_LOAD_F) < 6) {
  1929.       statements[numstatements - 1].op = OP_ADDRESS;
  1930.       def_pointer.type->aux_type = e->type;
  1931.       e->type = def_pointer.type;
  1932.     }
  1933.     e2 = PR_Expression(priority);
  1934.       }
  1935.       else
  1936.     e2 = PR_Expression(priority - 1);
  1937.  
  1938.       /* type check */
  1939.       type_a = e->type->type;
  1940.       type_b = e2->type->type;
  1941.  
  1942.       if (op->name[0] == '.') {                    /* field access gets type from field */
  1943.     if (e2->type->aux_type)
  1944.       type_c = e2->type->aux_type->type;
  1945.     else
  1946.       type_c = -1;                        /* not a field */
  1947.  
  1948.       }
  1949.       else
  1950.     type_c = ev_void;
  1951.  
  1952.       oldop = op;
  1953.       while (type_a != op->type_a->type->type
  1954.          || type_b != op->type_b->type->type
  1955.          || (type_c != ev_void && type_c != op->type_c->type->type)) {
  1956.     op++;
  1957.     if (!op->name || __strcmp(op->name, oldop->name))
  1958.       PR_ParseError("type mismatch for %s", oldop->name);
  1959.       }
  1960.  
  1961.       if (type_a == ev_pointer && type_b != e->type->aux_type->type)
  1962.     PR_ParseError("type mismatch for %s", op->name);
  1963.  
  1964.       if (op->right_associative)
  1965.     e = PR_Statement(op, e2, e);
  1966.       else
  1967.     e = PR_Statement(op, e, e2);
  1968.  
  1969.       if (type_c != ev_void)                    /* field access gets type from field */
  1970.     e->type = e2->type->aux_type;
  1971.  
  1972.       break;
  1973.     }
  1974.     if (!op->name)
  1975.       break;                            /* next token isn't at this priority level */
  1976.  
  1977.   }
  1978.  
  1979.   return e;
  1980. }
  1981.  
  1982. /*
  1983.  * ============
  1984.  * PR_ParseStatement
  1985.  * 
  1986.  * ============
  1987.  */
  1988. void PR_ParseDefs(void);
  1989. void PR_ParseStatement(void)
  1990. {
  1991.   def_t *e;
  1992.   dstatement_t *patch1, *patch2;
  1993.  
  1994.   if (PR_Check("{")) {
  1995.     do {
  1996.       PR_ParseStatement();
  1997.     } while (!PR_Check("}"));
  1998.     return;
  1999.   }
  2000.  
  2001.   if (PR_Check("return")) {
  2002.     if (PR_Check(";")) {
  2003.       PR_Statement(&pr_opcodes[OP_RETURN], 0, 0);
  2004.       return;
  2005.     }
  2006.     e = PR_Expression(TOP_PRIORITY);
  2007.     PR_Expect(";");
  2008.     PR_Statement(&pr_opcodes[OP_RETURN], e, 0);
  2009.     return;
  2010.   }
  2011.  
  2012.   if (PR_Check("while")) {
  2013.     PR_Expect("(");
  2014.     patch2 = &statements[numstatements];
  2015.     e = PR_Expression(TOP_PRIORITY);
  2016.     PR_Expect(")");
  2017.     patch1 = &statements[numstatements];
  2018.     PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
  2019.     PR_ParseStatement();
  2020.     junkdef.ofs = patch2 - &statements[numstatements];
  2021.     PR_Statement(&pr_opcodes[OP_GOTO], &junkdef, 0);
  2022.     patch1->b = &statements[numstatements] - patch1;
  2023.     return;
  2024.   }
  2025.  
  2026.   if (PR_Check("do")) {
  2027.     patch1 = &statements[numstatements];
  2028.     PR_ParseStatement();
  2029.     PR_Expect("while");
  2030.     PR_Expect("(");
  2031.     e = PR_Expression(TOP_PRIORITY);
  2032.     PR_Expect(")");
  2033.     PR_Expect(";");
  2034.     junkdef.ofs = patch1 - &statements[numstatements];
  2035.     PR_Statement(&pr_opcodes[OP_IF], e, &junkdef);
  2036.     return;
  2037.   }
  2038.  
  2039.   if (PR_Check("local")) {
  2040.     PR_ParseDefs();
  2041.     locals_end = numpr_globals;
  2042.     return;
  2043.   }
  2044.  
  2045.   if (PR_Check("if")) {
  2046.     PR_Expect("(");
  2047.     e = PR_Expression(TOP_PRIORITY);
  2048.     PR_Expect(")");
  2049.  
  2050.     patch1 = &statements[numstatements];
  2051.     PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
  2052.  
  2053.     PR_ParseStatement();
  2054.  
  2055.     if (PR_Check("else")) {
  2056.       patch2 = &statements[numstatements];
  2057.       PR_Statement(&pr_opcodes[OP_GOTO], 0, 0);
  2058.       patch1->b = &statements[numstatements] - patch1;
  2059.       PR_ParseStatement();
  2060.       patch2->a = &statements[numstatements] - patch2;
  2061.     }
  2062.     else
  2063.       patch1->b = &statements[numstatements] - patch1;
  2064.  
  2065.     return;
  2066.   }
  2067.  
  2068.   PR_Expression(TOP_PRIORITY);
  2069.   PR_Expect(";");
  2070. }
  2071.  
  2072. /*
  2073.  * ==============
  2074.  * PR_ParseState
  2075.  * 
  2076.  * States are special functions made for convenience.  They automatically
  2077.  * set frame, nextthink (implicitly), and think (allowing forward definitions).
  2078.  * 
  2079.  * // void() name = [framenum, nextthink] {code}
  2080.  * // expands to:
  2081.  * // function void name ()
  2082.  * // {
  2083.  * //           self.frame=framenum;
  2084.  * //           self.nextthink = time + 0.1;
  2085.  * //           self.think = nextthink
  2086.  * //           <code>
  2087.  * // };
  2088.  * ==============
  2089.  */
  2090. void PR_ParseState(void)
  2091. {
  2092.   char *name;
  2093.   def_t *s1, *def;
  2094.  
  2095.   if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
  2096.     PR_ParseError("state frame must be a number");
  2097.   s1 = PR_ParseImmediate();
  2098.  
  2099.   PR_Expect(",");
  2100.  
  2101.   name = PR_ParseName();
  2102.   def = PR_GetDef(&type_function, name, 0, TRUE);
  2103.  
  2104.   PR_Expect("]");
  2105.  
  2106.   PR_Statement(&pr_opcodes[OP_STATE], s1, def);
  2107. }
  2108.  
  2109. /*
  2110.  * ============
  2111.  * PR_ParseImmediateStatements
  2112.  * 
  2113.  * Parse a function body
  2114.  * ============
  2115.  */
  2116. function_t *PR_ParseImmediateStatements(register type_t * type)
  2117. {
  2118.   int i;
  2119.   function_t *f;
  2120.   def_t *defs[MAX_PARMS];
  2121.  
  2122.   f = (function_t *) kmalloc(sizeof(function_t));
  2123.  
  2124.   /*
  2125.    * check for builtin function definition #1, #2, etc
  2126.    */
  2127.   if (PR_Check("#")) {
  2128.     if (pr_token_type != tt_immediate
  2129.     || pr_immediate_type != &type_float
  2130.     || pr_immediate._float != (int)pr_immediate._float)
  2131.       PR_ParseError("Bad builtin immediate");
  2132.     f->builtin = (int)pr_immediate._float;
  2133.     PR_Lex();
  2134.     return f;
  2135.   }
  2136.  
  2137.   f->builtin = 0;
  2138.   /*
  2139.    * define the parms
  2140.    */
  2141.   for (i = 0; i < type->num_parms; i++) {
  2142.     defs[i] = PR_GetDef(type->parm_types[i], pr_parm_names[i], pr_scope, TRUE);
  2143.     f->parm_ofs[i] = defs[i]->ofs;
  2144.     if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
  2145.       PR_ParseError("bad parm order");
  2146.   }
  2147.  
  2148.   f->code = numstatements;
  2149.  
  2150.   /*
  2151.    * check for a state opcode
  2152.    */
  2153.   if (PR_Check("["))
  2154.     PR_ParseState();
  2155.  
  2156.   /*
  2157.    * parse regular statements
  2158.    */
  2159.   PR_Expect("{");
  2160.  
  2161.   while (!PR_Check("}"))
  2162.     PR_ParseStatement();
  2163.  
  2164.   /* emit an end of statements opcode */
  2165.   PR_Statement(pr_opcodes, 0, 0);
  2166.  
  2167.   return f;
  2168. }
  2169.  
  2170. /*
  2171.  * ================
  2172.  * PR_ParseDefs
  2173.  * 
  2174.  * Called at the outer layer and when a local statement is hit
  2175.  * ================
  2176.  */
  2177. void PR_ParseDefs(void)
  2178. {
  2179.   char *name;
  2180.   type_t *type;
  2181.   def_t *def;
  2182.   function_t *f;
  2183.   dfunction_t *df;
  2184.   int i;
  2185.   int locals_start;
  2186.  
  2187.   type = PR_ParseType();
  2188.  
  2189.   if (pr_scope && (type->type == ev_field || type->type == ev_function))
  2190.     PR_ParseError("Fields and functions must be global");
  2191.  
  2192.   do {
  2193.     name = PR_ParseName();
  2194.  
  2195.     def = PR_GetDef(type, name, pr_scope, TRUE);
  2196.  
  2197.     /* check for an initialization */
  2198.     if (PR_Check("=")) {
  2199.       if (def->initialized)
  2200.     PR_ParseError("%s redeclared", name);
  2201.  
  2202.       if (type->type == ev_function) {
  2203.     locals_start = locals_end = numpr_globals;
  2204.     pr_scope = def;
  2205.     f = PR_ParseImmediateStatements(type);
  2206.     pr_scope = NULL;
  2207.     def->initialized = 1;
  2208.     G_FUNCTION(def->ofs) = numfunctions;
  2209.     f->def = def;
  2210.     /*                              if (pr_dumpasm) */
  2211.     /*                                      PR_PrintFunction (def); */
  2212.  
  2213.     /* fill in the dfunction */
  2214.     df = &functions[numfunctions];
  2215.     numfunctions++;
  2216.     if (f->builtin)
  2217.       df->first_statement = -f->builtin;
  2218.     else
  2219.       df->first_statement = f->code;
  2220.     df->s_name = CopyString(f->def->name);
  2221.     df->s_file = s_file;
  2222.     df->numparms = f->def->type->num_parms;
  2223.     df->locals = locals_end - locals_start;
  2224.     df->parm_start = locals_start;
  2225.     for (i = 0; i < df->numparms; i++)
  2226.       df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
  2227.  
  2228.     continue;
  2229.       }
  2230.       else if (pr_immediate_type != type)
  2231.     PR_ParseError("wrong immediate type for %s", name);
  2232.  
  2233.       def->initialized = 1;
  2234.       memcpy(pr_globals + def->ofs, &pr_immediate, 4 * type_size[pr_immediate_type->type]);
  2235.       PR_Lex();
  2236.     }
  2237.  
  2238.   } while (PR_Check(","));
  2239.  
  2240.   PR_Expect(";");
  2241. }
  2242.  
  2243. /*
  2244.  * ============
  2245.  * PR_CompileFile
  2246.  * 
  2247.  * compiles the 0 terminated text, adding defintions to the pr structure
  2248.  * ============
  2249.  */
  2250. bool PR_CompileFile(register char *string, register char *filename)
  2251. {
  2252.   if (!pr.memory) {
  2253.     eprintf("PR_CompileFile: Didn't clear");
  2254.     return FALSE;
  2255.   }
  2256.  
  2257.   PR_ClearGrabMacros();                        /* clear the frame macros */
  2258.  
  2259.   pr_file_p = string;
  2260.   s_file = CopyString(filename);
  2261.  
  2262.   pr_source_line = 0;
  2263.  
  2264.   PR_NewLine();
  2265.  
  2266.   PR_Lex();                            /* read first token */
  2267.  
  2268.   while (pr_token_type != tt_eof) {
  2269.     if (setjmp(pr_parse_abort)) {
  2270.       if (++pr_error_count > MAX_ERRORS)
  2271.     return FALSE;
  2272.       PR_SkipToSemicolon();
  2273.       if (pr_token_type == tt_eof)
  2274.     return FALSE;
  2275.     }
  2276.  
  2277.     pr_scope = NULL;                        /* outside all functions */
  2278.  
  2279.     PR_ParseDefs();
  2280.   }
  2281.  
  2282.   return (pr_error_count == 0);
  2283. }
  2284. /*
  2285.  * ===============
  2286.  * PR_String
  2287.  * 
  2288.  * Returns a string suitable for printing (no newlines, max 60 chars length)
  2289.  * ===============
  2290.  */
  2291. char *PR_String(register char *string)
  2292. {
  2293.   static char buf[80];
  2294.   char *s;
  2295.  
  2296.   s = buf;
  2297.   *s++ = '"';
  2298.   while (string && *string) {
  2299.     if (s == buf + sizeof(buf) - 2)
  2300.       break;
  2301.     if (*string == '\n') {
  2302.       *s++ = '\\';
  2303.       *s++ = 'n';
  2304.     }
  2305.     else if (*string == '"') {
  2306.       *s++ = '\\';
  2307.       *s++ = '"';
  2308.     }
  2309.     else
  2310.       *s++ = *string;
  2311.     string++;
  2312.     if (s - buf > 60) {
  2313.       *s++ = '.';
  2314.       *s++ = '.';
  2315.       *s++ = '.';
  2316.       break;
  2317.     }
  2318.   }
  2319.   *s++ = '"';
  2320.   *s++ = 0;
  2321.   return buf;
  2322. }
  2323.  
  2324. def_t *PR_DefForFieldOfs(register gofs_t ofs)
  2325. {
  2326.   def_t *d;
  2327.  
  2328.   for (d = pr.def_head; d; d = d->next) {
  2329.     if (d->type->type != ev_field)
  2330.       continue;
  2331.     if (*((int *)&pr_globals[d->ofs]) == ofs)
  2332.       return d;
  2333.   }
  2334.   eprintf("PR_DefForFieldOfs: couldn't find %i", ofs);
  2335.   return NULL;
  2336. }
  2337.  
  2338. /*
  2339.  * ============
  2340.  * PR_ValueString
  2341.  * 
  2342.  * Returns a string describing *data in a type specific manner
  2343.  * =============
  2344.  */
  2345. char *PR_ValueString(register etype_t type, register void *val)
  2346. {
  2347.   static char line[256];
  2348.   def_t *def;
  2349.   dfunction_t *f;
  2350.  
  2351.   switch (type) {
  2352.     case ev_string:
  2353.       sprintf(line, "%s", PR_String(strings + *(int *)val));
  2354.       break;
  2355.     case ev_entity:
  2356.       sprintf(line, "entity %i", *(int *)val);
  2357.       break;
  2358.     case ev_function:
  2359.       f = functions + *(int *)val;
  2360.       if (!f)
  2361.     sprintf(line, "undefined function");
  2362.       else
  2363.     sprintf(line, "%s()", strings + f->s_name);
  2364.       break;
  2365.     case ev_field:
  2366.       def = PR_DefForFieldOfs(*(int *)val);
  2367.       sprintf(line, ".%s", def->name);
  2368.       break;
  2369.     case ev_void:
  2370.       sprintf(line, "void");
  2371.       break;
  2372.     case ev_float:
  2373.       sprintf(line, "%g", *(float *)val);
  2374.       break;
  2375.     case ev_vector:
  2376.       sprintf(line, "'%g %g %g'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  2377.       break;
  2378.     case ev_pointer:
  2379.       sprintf(line, "pointer");
  2380.       break;
  2381.     default:
  2382.       sprintf(line, "bad type %i", type);
  2383.       break;
  2384.   }
  2385.  
  2386.   return line;
  2387. }
  2388.  
  2389. /*
  2390.  * ============
  2391.  * PR_GlobalString
  2392.  * 
  2393.  * Returns a string with a description and the contents of a global,
  2394.  * padded to 20 field width
  2395.  * ============
  2396.  */
  2397. char *PR_GlobalStringNoContents(register gofs_t ofs)
  2398. {
  2399.   int i;
  2400.   def_t *def;
  2401.  
  2402.   /*void *val; */
  2403.   static char line[128];
  2404.  
  2405.   /*val = (void *)&pr_globals[ofs]; */
  2406.   def = pr_global_defs[ofs];
  2407.   if (!def)
  2408.     /* Error ("PR_GlobalString: no def for %i", ofs); */
  2409.     sprintf(line, "%i(???)", ofs);
  2410.   else
  2411.     sprintf(line, "%i(%s)", ofs, def->name);
  2412.  
  2413.   i = __strlen(line);
  2414.   for (; i < 16; i++)
  2415.     __strcat(line, " ");
  2416.   __strcat(line, " ");
  2417.  
  2418.   return line;
  2419. }
  2420.  
  2421. char *PR_GlobalString(register gofs_t ofs)
  2422. {
  2423.   char *s;
  2424.   int i;
  2425.   def_t *def;
  2426.  
  2427.   /*void *val; */
  2428.   static char line[128];
  2429.  
  2430.   /*val = (void *)&pr_globals[ofs]; */
  2431.   def = pr_global_defs[ofs];
  2432.   if (!def)
  2433.     return PR_GlobalStringNoContents(ofs);
  2434.   if (def->initialized && def->type->type != ev_function) {
  2435.     s = PR_ValueString(def->type->type, &pr_globals[ofs]);
  2436.     sprintf(line, "%i(%s)", ofs, s);
  2437.   }
  2438.   else
  2439.     sprintf(line, "%i(%s)", ofs, def->name);
  2440.  
  2441.   i = __strlen(line);
  2442.   for (; i < 16; i++)
  2443.     __strcat(line, " ");
  2444.   __strcat(line, " ");
  2445.  
  2446.   return line;
  2447. }
  2448.  
  2449. /*
  2450.  * ============
  2451.  * PR_PrintOfs
  2452.  * ============
  2453.  */
  2454. void PR_PrintOfs(register gofs_t ofs)
  2455. {
  2456.   mprintf("%s\n", PR_GlobalString(ofs));
  2457. }
  2458.  
  2459. /*
  2460.  * =================
  2461.  * PR_PrintStatement
  2462.  * =================
  2463.  */
  2464. void PR_PrintStatement(register dstatement_t * s)
  2465. {
  2466.   int i;
  2467.  
  2468.   mprintf("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s - statements], pr_opcodes[s->op].opname);
  2469.   i = __strlen(pr_opcodes[s->op].opname);
  2470.   for (; i < 10; i++)
  2471.     mprintf(" ");
  2472.  
  2473.   if (s->op == OP_IF || s->op == OP_IFNOT)
  2474.     mprintf("%sbranch %i", PR_GlobalString(s->a), s->b);
  2475.   else if (s->op == OP_GOTO) {
  2476.     mprintf("branch %i", s->a);
  2477.   }
  2478.   else if ((unsigned)(s->op - OP_STORE_F) < 6) {
  2479.     mprintf("%s", PR_GlobalString(s->a));
  2480.     mprintf("%s", PR_GlobalStringNoContents(s->b));
  2481.   }
  2482.   else {
  2483.     if (s->a)
  2484.       mprintf("%s", PR_GlobalString(s->a));
  2485.     if (s->b)
  2486.       mprintf("%s", PR_GlobalString(s->b));
  2487.     if (s->c)
  2488.       mprintf("%s", PR_GlobalStringNoContents(s->c));
  2489.   }
  2490.   mprintf("\n");
  2491. }
  2492.  
  2493. /*
  2494.  * ============
  2495.  * PR_PrintDefs
  2496.  * ============
  2497.  */
  2498. void PR_PrintDefs(void)
  2499. {
  2500.   def_t *d;
  2501.  
  2502.   for (d = pr.def_head; d; d = d->next)
  2503.     PR_PrintOfs(d->ofs);
  2504. }
  2505.  
  2506. /*
  2507.  * ==============
  2508.  * PR_BeginCompilation
  2509.  * 
  2510.  * called before compiling a batch of files, clears the pr struct
  2511.  * ==============
  2512.  */
  2513. void PR_BeginCompilation(register void *memory, register int memsize)
  2514. {
  2515.   int i;
  2516.  
  2517.   pr.memory = memory;
  2518.   pr.max_memory = memsize;
  2519.  
  2520.   numpr_globals = RESERVED_OFS;
  2521.   pr.def_tail = NULL;
  2522.  
  2523.   for (i = 0; i < RESERVED_OFS; i++)
  2524.     pr_global_defs[i] = &def_void;
  2525.  
  2526.   /* link the function type in so state forward declarations match proper type */
  2527.   pr.types = &type_function;
  2528.   type_function.next = NULL;
  2529.   pr_error_count = 0;
  2530. }
  2531.  
  2532. /*
  2533.  * ==============
  2534.  * PR_FinishCompilation
  2535.  * 
  2536.  * called after all files are compiled to check for errors
  2537.  * Returns FALSE if errors were detected.
  2538.  * ==============
  2539.  */
  2540. bool PR_FinishCompilation(void)
  2541. {
  2542.   def_t *d;
  2543.   bool errors;
  2544.  
  2545.   errors = FALSE;
  2546.  
  2547.   /* check to make sure all functions prototyped have code */
  2548.   for (d = pr.def_head; d; d = d->next) {
  2549.     /* function parms are ok */
  2550.     if (d->type->type == ev_function && !d->scope) {
  2551.       /* f = G_FUNCTION(d->ofs); */
  2552.       /* if (!f || (!f->code && !f->builtin) ) */
  2553.       if (!d->initialized) {
  2554.     eprintf("function %s was not defined\n", d->name);
  2555.     errors = TRUE;
  2556.       }
  2557.     }
  2558.   }
  2559.  
  2560.   return !errors;
  2561. }
  2562.  
  2563. /*============================================================================= */
  2564.  
  2565. /*
  2566.  * ============
  2567.  * PR_WriteProgdefs
  2568.  * 
  2569.  * Writes the global and entity structures out
  2570.  * Returns a crc of the header, to be stored in the progs file for comparison
  2571.  * at load time.
  2572.  * ============
  2573.  */
  2574. int PR_WriteProgdefs(register char *filename)
  2575. {
  2576.   def_t *d;
  2577.   FILE *f;
  2578.   unsigned short int crc;
  2579.   int c;
  2580.  
  2581.   mprintf("writing %s\n", filename);
  2582.   f = fopen(filename, "w");
  2583.  
  2584.   /* print global vars until the first field is defined */
  2585.   fprintf(f, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS);
  2586.   for (d = pr.def_head; d; d = d->next) {
  2587.     if (!__strcmp(d->name, "end_sys_globals"))
  2588.       break;
  2589.  
  2590.     switch (d->type->type) {
  2591.       case ev_float:
  2592.     fprintf(f, "\tfloat\t%s;\n", d->name);
  2593.     break;
  2594.       case ev_vector:
  2595.     fprintf(f, "\tvec3_t\t%s;\n", d->name);
  2596.     d = d->next->next->next;                /* skip the elements */
  2597.  
  2598.     break;
  2599.       case ev_string:
  2600.     fprintf(f, "\tstring_t\t%s;\n", d->name);
  2601.     break;
  2602.       case ev_function:
  2603.     fprintf(f, "\tfunc_t\t%s;\n", d->name);
  2604.     break;
  2605.       case ev_entity:
  2606.     fprintf(f, "\tint\t%s;\n", d->name);
  2607.     break;
  2608.       default:
  2609.     fprintf(f, "\tint\t%s;\n", d->name);
  2610.     break;
  2611.     }
  2612.   }
  2613.   fprintf(f, "} globalvars_t;\n\n");
  2614.  
  2615.   /* print all fields */
  2616.   fprintf(f, "typedef struct\n{\n");
  2617.   for (d = pr.def_head; d; d = d->next) {
  2618.     if (!__strcmp(d->name, "end_sys_fields"))
  2619.       break;
  2620.  
  2621.     if (d->type->type != ev_field)
  2622.       continue;
  2623.  
  2624.     switch (d->type->aux_type->type) {
  2625.       case ev_float:
  2626.     fprintf(f, "\tfloat\t%s;\n", d->name);
  2627.     break;
  2628.       case ev_vector:
  2629.     fprintf(f, "\tvec3_t\t%s;\n", d->name);
  2630.     d = d->next->next->next;                /* skip the elements */
  2631.  
  2632.     break;
  2633.       case ev_string:
  2634.     fprintf(f, "\tstring_t\t%s;\n", d->name);
  2635.     break;
  2636.       case ev_function:
  2637.     fprintf(f, "\tfunc_t\t%s;\n", d->name);
  2638.     break;
  2639.       case ev_entity:
  2640.     fprintf(f, "\tint\t%s;\n", d->name);
  2641.     break;
  2642.       default:
  2643.     fprintf(f, "\tint\t%s;\n", d->name);
  2644.     break;
  2645.     }
  2646.   }
  2647.   fprintf(f, "} entvars_t;\n\n");
  2648.  
  2649.   fclose(f);
  2650.  
  2651.   /* do a crc of the file */
  2652.   CRC_Init(&crc);
  2653.   f = fopen(filename, "r+");
  2654.   while ((c = fgetc(f)) != EOF)
  2655.     CRC_ProcessByte(&crc, (unsigned char)c);
  2656.  
  2657.   fprintf(f, "#define PROGHEADER_CRC %i\n", crc);
  2658.   fclose(f);
  2659.  
  2660.   return crc;
  2661. }
  2662.  
  2663. void PrintFunction(register char *name)
  2664. {
  2665.   int i;
  2666.   dstatement_t *ds;
  2667.   dfunction_t *df;
  2668.  
  2669.   for (i = 0; i < numfunctions; i++)
  2670.     if (!__strcmp(name, strings + functions[i].s_name))
  2671.       break;
  2672.   if (i == numfunctions)
  2673.     eprintf("No function names \"%s\"", name);
  2674.   else {
  2675.     df = functions + i;
  2676.  
  2677.     mprintf("Statements for %s:\n", name);
  2678.     ds = statements + df->first_statement;
  2679.     while (1) {
  2680.       PR_PrintStatement(ds);
  2681.       if (!ds->op)
  2682.     break;
  2683.       ds++;
  2684.     }
  2685.   }
  2686. }
  2687.  
  2688. /*============================================================================ */
  2689.  
  2690. char com_token[1024];
  2691. bool com_eof;
  2692.  
  2693. /*
  2694.  * ==============
  2695.  * COM_Parse
  2696.  * 
  2697.  * Parse a token out of a string
  2698.  * ==============
  2699.  */
  2700. char *COM_Parse(register char *data)
  2701. {
  2702.   int c;
  2703.   int len;
  2704.  
  2705.   len = 0;
  2706.   com_token[0] = 0;
  2707.  
  2708.   if (!data)
  2709.     return NULL;
  2710.  
  2711.   /* skip whitespace */
  2712. skipwhite:
  2713.   while ((c = *data) <= ' ') {
  2714.     if (c == 0) {
  2715.       com_eof = TRUE;
  2716.       return NULL;                        /* end of file; */
  2717.  
  2718.     }
  2719.     data++;
  2720.   }
  2721.  
  2722.   /* skip // comments */
  2723.   if (c == '/' && data[1] == '/') {
  2724.     while (*data && *data != '\n')
  2725.       data++;
  2726.     goto skipwhite;
  2727.   }
  2728.  
  2729.   /* handle quoted strings specially */
  2730.   if (c == '\"') {
  2731.     data++;
  2732.     do {
  2733.       c = *data++;
  2734.       if (c == '\"') {
  2735.     com_token[len] = 0;
  2736.     return data;
  2737.       }
  2738.       com_token[len] = c;
  2739.       len++;
  2740.     } while (1);
  2741.   }
  2742.  
  2743.   /* parse single characters */
  2744.   if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') {
  2745.     com_token[len] = c;
  2746.     len++;
  2747.     com_token[len] = 0;
  2748.     return data + 1;
  2749.   }
  2750.  
  2751.   /* parse a regular word */
  2752.   do {
  2753.     com_token[len] = c;
  2754.     data++;
  2755.     len++;
  2756.     c = *data;
  2757.     if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':')
  2758.       break;
  2759.   } while (c > 32);
  2760.  
  2761.   com_token[len] = 0;
  2762.   return data;
  2763. }
  2764.  
  2765. /*=========================================================================== */
  2766. /*unqcc */
  2767. /*=========================================================================== */
  2768.  
  2769. FILE *DEC_ofile;
  2770. FILE *DEC_progssrc;
  2771.  
  2772. #ifdef    QC_PROFILE
  2773. FILE *DEC_profile;
  2774.  
  2775. #endif
  2776. char *DEC_FilesSeen[1024];
  2777. int DEC_FileCtr = 0;
  2778. char *DEC_Profiles[MAX_FUNCTIONS];
  2779.  
  2780. char *type_names[8] =
  2781. {"void", "string", "float", "vector", "entity", "ev_field", "void()", "ev_pointer"};
  2782.  
  2783. char *builtins[79] =
  2784. {
  2785.   NULL,
  2786.   "void (vector ang)",
  2787.   "void (entity e, vector o)",
  2788.   "void (entity e, string m)",
  2789.   "void (entity e, vector min, vector max)",
  2790.   NULL,
  2791.   "void ()",
  2792.   "float ()",
  2793.   "void (entity e, float chan, string samp, float vol, float atten)",
  2794.   "vector (vector v)",
  2795.   "void (string e)",
  2796.   "void (string e)",
  2797.   "float (vector v)",
  2798.   "float (vector v)",
  2799.   "entity ()",
  2800.   "void (entity e)",
  2801.   "void (vector v1, vector v2, float nomonsters, entity forent)",
  2802.   "entity ()",
  2803.   "entity (entity start, .string fld, string match)",
  2804.   "string (string s)",
  2805.   "string (string s)",
  2806.   "void (entity client, string s)",
  2807.   "entity (vector org, float rad)",
  2808.   "void (string s)",
  2809.   "void (entity client, string s)",
  2810.   "void (string s)",
  2811.   "string (float f)",
  2812.   "string (vector v)",
  2813.   "void ()",
  2814.   "void ()",
  2815.   "void ()",
  2816.   "void (entity e)",
  2817.   "float (float yaw, float dist)",
  2818.   NULL,
  2819.   "float (float yaw, float dist)",
  2820.   "void (float style, string value)",
  2821.   "float (float v)",
  2822.   "float (float v)",
  2823.   "float (float v)",
  2824.   NULL,
  2825.   "float (entity e)",
  2826.   "float (vector v)",
  2827.   NULL,
  2828.   "float (float f)",
  2829.   "vector (entity e, float speed)",
  2830.   "float (string s)",
  2831.   "void (string s)",
  2832.   "entity (entity e)",
  2833.   "void (vector o, vector d, float color, float count)",
  2834.   "void ()",
  2835.   NULL,
  2836.   "vector (vector v)",
  2837.   "void (float to, float f)",
  2838.   "void (float to, float f)",
  2839.   "void (float to, float f)",
  2840.   "void (float to, float f)",
  2841.   "void (float to, float f)",
  2842.   "void (float to, float f)",
  2843.   "void (float to, string s)",
  2844.   "void (float to, entity s)",
  2845.   NULL,
  2846.   NULL,
  2847.   NULL,
  2848.   NULL,
  2849.   NULL,
  2850.   NULL,
  2851.   NULL,
  2852.   "void (float step)",
  2853.   "string (string s)",
  2854.   "void (entity e)",
  2855.   "void (string s)",
  2856.   NULL,
  2857.   "void (string var, string val)",
  2858.   "void (entity client, string s)",
  2859.   "void (vector pos, string samp, float vol, float atten)",
  2860.   "string (string s)",
  2861.   "string (string s)",
  2862.   "string (string s)",
  2863.   "void (entity e)"
  2864. };
  2865.  
  2866. int DEC_GetFunctionIdxByName(register char *name)
  2867. {
  2868.   int i;
  2869.  
  2870.   for (i = 1; i < numfunctions; i++)
  2871.     if (!__strcmp(name, strings + functions[i].s_name)) {
  2872.       break;
  2873.     }
  2874.   return i;
  2875. }
  2876.  
  2877. int DEC_AlreadySeen(register char *fname)
  2878. {
  2879.   int i;
  2880.   char *new;
  2881.  
  2882.   if (DEC_FileCtr > 1000)
  2883.     eprintf("DEC_AlreadySeen - too many source files.");
  2884.   else {
  2885.     for (i = 0; i < DEC_FileCtr; i++) {
  2886.       if (!__strcmp(fname, DEC_FilesSeen[i]))
  2887.     return 1;
  2888.     }
  2889.  
  2890.     /*new = (char *)kmalloc(__strlen(fname) + 1); */
  2891. /*__strcpy(new, fname); */
  2892.     new = smalloc(fname);
  2893.     DEC_FilesSeen[DEC_FileCtr] = new;
  2894.     DEC_FileCtr++;
  2895.  
  2896.     mprintf("decompiling %s\n", fname);
  2897.   }
  2898.   return 0;
  2899. }
  2900.  
  2901. ddef_t *DEC_GetParameter(register gofs_t ofs)
  2902. {
  2903.   int i;
  2904.   ddef_t *def;
  2905.  
  2906.   def = NULL;
  2907.  
  2908.   for (i = 0; i < numglobaldefs; i++) {
  2909.     def = &globals[i];
  2910.  
  2911.     if (def->ofs == ofs) {
  2912.       return def;
  2913.     }
  2914.   }
  2915.  
  2916.   return NULL;
  2917. }
  2918.  
  2919. /*
  2920.  * fix: same as PR_String
  2921.  */
  2922. char *DEC_String(register char *string)
  2923. {
  2924.   static char buf[255];
  2925.   char *s;
  2926.   int c = 1;
  2927.  
  2928.   s = buf;
  2929.   *s++ = '"';
  2930.   while (string && *string) {
  2931.     if (c == sizeof(buf) - 2)
  2932.       break;
  2933.     if (*string == '\n') {
  2934.       *s++ = '\\';
  2935.       *s++ = 'n';
  2936.       c++;
  2937.     }
  2938.     else if (*string == '"') {
  2939.       *s++ = '\\';
  2940.       *s++ = '"';
  2941.       c++;
  2942.     }
  2943.     else {
  2944.       *s++ = *string;
  2945.       c++;
  2946.     }
  2947.     string++;
  2948.     if (c > sizeof(buf) - 10) {
  2949.       *s++ = '.';
  2950.       *s++ = '.';
  2951.       *s++ = '.';
  2952.       c += 3;
  2953.       break;
  2954.     }
  2955.   }
  2956.   *s++ = '"';
  2957.   *s++ = 0;
  2958.   return buf;
  2959. }
  2960.  
  2961. /*
  2962.  * fix: same as PR_ValueString
  2963.  */
  2964. char *DEC_ValueString(register etype_t type, register void *val)
  2965. {
  2966.   static char line[1024];
  2967.  
  2968.   line[0] = '\0';
  2969.  
  2970.   switch (type) {
  2971.     case ev_string:
  2972.       sprintf(line, "%s", DEC_String(strings + *(int *)val));
  2973.       break;
  2974.     case ev_void:
  2975.       sprintf(line, "void");
  2976.       break;
  2977.     case ev_float:
  2978.       sprintf(line, "%g", *(float *)val);
  2979.       break;
  2980.     case ev_vector:
  2981.       sprintf(line, "'%g %g %g'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  2982.       break;
  2983.     default:
  2984.       sprintf(line, "bad type %i", type);
  2985.       break;
  2986.   }
  2987.  
  2988.   return line;
  2989. }
  2990.  
  2991. char *DEC_PrintParameter(register ddef_t * def)
  2992. {
  2993.   static char line[128];
  2994.  
  2995.   line[0] = '0';
  2996.  
  2997.   if (!__strcmp(strings + def->s_name, "IMMEDIATE")) {
  2998.     sprintf(line, "%s", DEC_ValueString(def->type, &pr_globals[def->ofs]));
  2999.   }
  3000.   else
  3001.     sprintf(line, "%s %s", type_names[def->type], strings + def->s_name);
  3002.  
  3003.   return line;
  3004. }
  3005.  
  3006. void DEC_CalcProfiles(void)
  3007. {
  3008.   int i, j, ps;
  3009.   static char fname[512];
  3010.   static char line[512];
  3011.   char *new;
  3012.   dfunction_t *df;
  3013.   dstatement_t *ds, *rds;
  3014.   ddef_t *par;
  3015.   unsigned short dom;
  3016.  
  3017.   for (i = 1; i < numfunctions; i++) {
  3018.     df = functions + i;
  3019.     fname[0] = '\0';
  3020.     line[0] = '\0';
  3021.     DEC_Profiles[i] = NULL;
  3022.  
  3023.     if (df->first_statement <= 0) {
  3024.       sprintf(fname, "%s %s", builtins[-df->first_statement], strings + functions[i].s_name);
  3025.     }
  3026.     else {
  3027.       ds = statements + df->first_statement;
  3028.       rds = NULL;
  3029.  
  3030.       /* find a return statement, to determine the result type */
  3031.  
  3032.       while (1) {
  3033.     dom = (ds->op) % 100;
  3034.     if (!dom)
  3035.       break;
  3036.     if (dom == OP_RETURN) {
  3037.       rds = ds;
  3038.       /*                  break;  */
  3039.     }
  3040.     ds++;
  3041.       }
  3042.  
  3043.       /* print the return type  */
  3044.       if ((rds != NULL) && (rds->a != 0)) {
  3045.     par = DEC_GetParameter(rds->a);
  3046.  
  3047.     if (par) {
  3048.       sprintf(fname, "%s ", type_names[par->type]);
  3049.     }
  3050.     else {
  3051.       sprintf(fname, "float /* ERROR: Could not determine return type */ ");
  3052.     }
  3053.       }
  3054.       else {
  3055.     sprintf(fname, "\nvoid ");
  3056.       }
  3057.       __strcat(fname, "(");
  3058.  
  3059.       /* determine overall parameter size */
  3060.  
  3061.       for (j = 0, ps = 0; j < df->numparms; j++)
  3062.     ps += df->parm_size[j];
  3063.  
  3064.       if (ps > 0) {
  3065.     for (j = df->parm_start; j < (df->parm_start) + ps; j++) {
  3066.       line[0] = '\0';
  3067.       par = DEC_GetParameter(j);
  3068.  
  3069.       if (!par)
  3070.         eprintf("DEC_CalcProfiles - No parameter names with offset %i.", j);
  3071.       else {
  3072.         if (par->type == ev_vector)
  3073.           j += 2;
  3074.  
  3075.         if (j < (df->parm_start) + ps - 1) {
  3076.           sprintf(line, "%s, ", DEC_PrintParameter(par));
  3077.         }
  3078.         else {
  3079.           sprintf(line, "%s", DEC_PrintParameter(par));
  3080.         }
  3081.         __strcat(fname, line);
  3082.       }
  3083.     }
  3084.       }
  3085.       __strcat(fname, ") ");
  3086.       line[0] = '\0';
  3087.       sprintf(line, strings + functions[i].s_name);
  3088.       __strcat(fname, line);
  3089.     }
  3090.  
  3091.     if (i >= MAX_FUNCTIONS)
  3092.       eprintf("DEC_CalcProfiles - too many functions.");
  3093.     else {
  3094.       /*new = (char *)kmalloc(__strlen(fname) + 1); */
  3095. /*__strcpy(new, fname); */
  3096.       new = smalloc(fname);
  3097.       DEC_Profiles[i] = new;
  3098.     }
  3099.   }
  3100. }
  3101.  
  3102. char *DEC_Global(register gofs_t ofs, register def_t * req_t)
  3103. {
  3104.   int i;
  3105.   ddef_t *def;
  3106.   static char line[256];
  3107.   char *res;
  3108.   char found = 0;
  3109.  
  3110.   line[0] = '\0';
  3111.  
  3112.   def = NULL;
  3113.  
  3114.   for (i = 0; i < numglobaldefs; i++) {
  3115.     def = &globals[i];
  3116.     if (def->ofs == ofs) {
  3117.       oprintf("DEC_Global - Found %i at %i.\n", ofs, (int)def);
  3118.       found = 1;
  3119.       break;
  3120.     }
  3121.   }
  3122.  
  3123.   if (found) {
  3124.     if (!__strcmp(strings + def->s_name, "IMMEDIATE"))
  3125.       sprintf(line, "%s", DEC_ValueString(def->type, &pr_globals[def->ofs]));
  3126.     else {
  3127.  
  3128.       sprintf(line, "%s", strings + def->s_name);
  3129.       if (def->type == ev_vector && req_t == &def_float)
  3130.     __strcat(line, "_x");
  3131.     }
  3132.     /*res = (char *)kmalloc(__strlen(line) + 1); */
  3133. /*__strcpy(res, line); */
  3134.     res = smalloc(line);
  3135.  
  3136.     oprintf("DEC_Global - Found \"%s\"(%i) at %i.\n", line, ofs, (int)def);
  3137.     return res;
  3138.  
  3139.   }
  3140.   return NULL;
  3141. }
  3142.  
  3143. gofs_t DEC_ScaleIndex(register dfunction_t * df, register gofs_t ofs)
  3144. {
  3145.   gofs_t nofs = 0;
  3146.  
  3147.   if (ofs > RESERVED_OFS)
  3148.     nofs = ofs - df->parm_start + RESERVED_OFS;
  3149.   else
  3150.     nofs = ofs;
  3151.  
  3152.   return nofs;
  3153. }
  3154.  
  3155. #define MAX_NO_LOCAL_IMMEDIATES 1024
  3156.  
  3157. char *DEC_Immediate(register dfunction_t * df, register gofs_t ofs, register int fun, register char *new)
  3158. {
  3159.   int i;
  3160.   gofs_t nofs;
  3161.   static char *IMMEDIATES[MAX_NO_LOCAL_IMMEDIATES];
  3162.  
  3163.   /*
  3164.    * free 'em all 
  3165.    */
  3166.   if (fun == 0) {
  3167.     oprintf("DEC_Immediate - Initializing function environment.\n");
  3168.     for (i = 0; i < MAX_NO_LOCAL_IMMEDIATES; i++)
  3169.       if (IMMEDIATES[i])
  3170.     tfree(IMMEDIATES[i]);
  3171.     bzero(&IMMEDIATES, MAX_NO_LOCAL_IMMEDIATES * sizeof(char *));
  3172.  
  3173.     return NULL;
  3174.   }
  3175.  
  3176.   nofs = DEC_ScaleIndex(df, ofs);
  3177.   oprintf("DEC_Immediate - Index scale: %i -> %i.\n", ofs, nofs);
  3178.  
  3179.   /*
  3180.    * check consistency 
  3181.    */
  3182.   if ((nofs <= 0) || (nofs > MAX_NO_LOCAL_IMMEDIATES - 1))
  3183.     eprintf("DEC_Immediate - Index (%i) out of bounds.\n", nofs);
  3184.   else {
  3185.     /*
  3186.      * insert at nofs 
  3187.      */
  3188.     if (fun == 1) {
  3189.       if (IMMEDIATES[nofs])
  3190.     tfree(IMMEDIATES[nofs]);
  3191.       IMMEDIATES[nofs] = smalloc(new);
  3192.       oprintf("DEC_Immediate - Putting \"%s\" at index %i.\n", new, nofs);
  3193.     }
  3194.  
  3195.     /*
  3196.      * get from nofs 
  3197.      */
  3198.     if (fun == 2) {
  3199.       if (IMMEDIATES[nofs]) {
  3200.     oprintf("DEC_Immediate - Reading \"%s\" at index %i.\n", IMMEDIATES[nofs], nofs);
  3201.     return smalloc(IMMEDIATES[nofs]);
  3202.       }
  3203.       else
  3204.     eprintf("DEC_Immediate - %i not defined.", nofs);
  3205.     }
  3206.   }
  3207.  
  3208.   return NULL;
  3209. }
  3210.  
  3211. char *DEC_Get(register dfunction_t * df, register gofs_t ofs, register def_t * req_t)
  3212. {
  3213.   char *arg1 = NULL;
  3214.  
  3215.   arg1 = DEC_Global(ofs, req_t);
  3216.  
  3217.   if (arg1 == NULL)
  3218.     arg1 = DEC_Immediate(df, ofs, 2, NULL);
  3219.  
  3220.   /*
  3221.    * if (arg1)
  3222.    * mprintf("DEC_Get - found \"%s\".\n",arg1);
  3223.    */
  3224.  
  3225.   return arg1;
  3226. }
  3227.  
  3228. void DEC_Indent(register int c)
  3229. {
  3230.   int i;
  3231.  
  3232.   if (c < 0)
  3233.     c = 0;
  3234.  
  3235.   for (i = 0; i < c; i++) {
  3236.     fprintf(DEC_ofile, "   ");
  3237.   }
  3238. }
  3239.  
  3240. void DEC_DecompileStatement(register dfunction_t * df, register dstatement_t * s, register int *indent)
  3241. {
  3242.   static char line[512];
  3243.   static char fnam[512];
  3244.   char *arg1, *arg2, *arg3;
  3245.   int nargs, i, j;
  3246.   dstatement_t *t;
  3247.   unsigned short dom, doc, ifc, tom;
  3248.   def_t *typ1, *typ2, *typ3;
  3249.  
  3250.   dstatement_t *k;
  3251.   int dum;
  3252.  
  3253.   arg1 = arg2 = arg3 = NULL;
  3254.  
  3255.   line[0] = '\0';
  3256.   fnam[0] = '\0';
  3257.  
  3258.   dom = s->op;
  3259.  
  3260.   doc = dom / 10000;
  3261.   ifc = (dom % 10000) / 100;
  3262.  
  3263.   /*
  3264.    * use program flow information 
  3265.    */
  3266.   for (i = 0; i < ifc; i++) {
  3267.     (*indent)--;
  3268.     fprintf(DEC_ofile, "\n");
  3269.     DEC_Indent(*indent);
  3270.     fprintf(DEC_ofile, "}\n");
  3271.   }
  3272.   for (i = 0; i < doc; i++) {
  3273.     DEC_Indent(*indent);
  3274.     fprintf(DEC_ofile, "do {\n\n");
  3275.     (*indent)++;
  3276.   }
  3277.  
  3278.   /*
  3279.    * remove all program flow information 
  3280.    */
  3281.   s->op %= 100;
  3282.  
  3283.   typ1 = pr_opcodes[s->op].type_a;
  3284.   typ2 = pr_opcodes[s->op].type_b;
  3285.   typ3 = pr_opcodes[s->op].type_c;
  3286.  
  3287.   /*
  3288.    * mprintf("DEC_DecompileStatement - decompiling %i (%i):\n",(int)(s - statements),dom);
  3289.    * DEC_PrintStatement (s);  
  3290.    */
  3291.   /* states are handled at top level */
  3292.   if (s->op == OP_DONE || s->op == OP_STATE) {
  3293.   }
  3294.   else if (s->op == OP_RETURN) {
  3295.     DEC_Indent(*indent);
  3296.     fprintf(DEC_ofile, "return ");
  3297.  
  3298.     if (s->a) {
  3299.       arg1 = DEC_Get(df, s->a, typ1);
  3300.       fprintf(DEC_ofile, "( %s )", arg1);
  3301.     }
  3302.  
  3303.     fprintf(DEC_ofile, ";\n");
  3304.   }
  3305.   else if ((OP_MUL_F <= s->op && s->op <= OP_SUB_V) ||
  3306.        (OP_EQ_F <= s->op && s->op <= OP_GT) ||
  3307.        (OP_AND <= s->op && s->op <= OP_BITOR)) {
  3308.     arg1 = DEC_Get(df, s->a, typ1);
  3309.     arg2 = DEC_Get(df, s->b, typ2);
  3310.     arg3 = DEC_Global(s->c, typ3);
  3311.  
  3312.     if (arg3) {
  3313.       DEC_Indent(*indent);
  3314.       fprintf(DEC_ofile, "%s = %s %s %s;\n", arg3, arg1, pr_opcodes[s->op].name, arg2);
  3315.     }
  3316.     else {
  3317.       sprintf(line, "(%s %s %s)", arg1, pr_opcodes[s->op].name, arg2);
  3318.       DEC_Immediate(df, s->c, 1, line);
  3319.     }
  3320.   }
  3321.   else if (OP_LOAD_F <= s->op && s->op <= OP_ADDRESS) {
  3322.     arg1 = DEC_Get(df, s->a, typ1);
  3323.     arg2 = DEC_Get(df, s->b, typ2);
  3324.     arg3 = DEC_Global(s->c, typ3);
  3325.  
  3326.     if (arg3) {
  3327.       DEC_Indent(*indent);
  3328.       fprintf(DEC_ofile, "%s = %s.%s;\n", arg3, arg1, arg2);
  3329.     }
  3330.     else {
  3331.       sprintf(line, "%s.%s", arg1, arg2);
  3332.       DEC_Immediate(df, s->c, 1, line);
  3333.     }
  3334.   }
  3335.   else if (OP_STORE_F <= s->op && s->op <= OP_STORE_FNC) {
  3336.     arg1 = DEC_Get(df, s->a, typ1);
  3337.     arg3 = DEC_Global(s->b, typ2);
  3338.  
  3339.     if (arg3) {
  3340.       DEC_Indent(*indent);
  3341.       fprintf(DEC_ofile, "%s = %s;\n", arg3, arg1);
  3342.     }
  3343.     else {
  3344.       sprintf(line, "%s", arg1);
  3345.       DEC_Immediate(df, s->b, 1, line);
  3346.     }
  3347.   }
  3348.   else if (OP_STOREP_F <= s->op && s->op <= OP_STOREP_FNC) {
  3349.     arg1 = DEC_Get(df, s->a, typ1);
  3350.     arg2 = DEC_Get(df, s->b, typ2);
  3351.  
  3352.     DEC_Indent(*indent);
  3353.     fprintf(DEC_ofile, "%s = %s;\n", arg2, arg1);
  3354.   }
  3355.   else if (OP_NOT_F <= s->op && s->op <= OP_NOT_FNC) {
  3356.     arg1 = DEC_Get(df, s->a, typ1);
  3357.     sprintf(line, "!%s", arg1);
  3358.     DEC_Immediate(df, s->c, 1, line);
  3359.   }
  3360.   else if (OP_CALL0 <= s->op && s->op <= OP_CALL8) {
  3361.     nargs = s->op - OP_CALL0;
  3362.     arg1 = DEC_Get(df, s->a, NULL);
  3363.     sprintf(line, "%s (", arg1);
  3364.     sprintf(fnam, "%s", arg1);
  3365.  
  3366.     for (i = 0; i < nargs; i++) {
  3367.       typ1 = NULL;
  3368.       j = 4 + 3 * i;
  3369.  
  3370.       if (arg1) {
  3371.     tfree(arg1);
  3372.     arg1 = 0;
  3373.       }
  3374.  
  3375.       arg1 = DEC_Get(df, j, typ1);
  3376.       __strcat(line, arg1);
  3377.  
  3378. #ifndef DONT_USE_DIRTY_TRICKS
  3379.       if (!__strcmp(fnam, "WriteCoord"))
  3380.     if (!__strcmp(arg1, "org") || !__strcmp(arg1, "trace_endpos") || !__strcmp(arg1, "p1") || !__strcmp(arg1, "p2") || !__strcmp(arg1, "o"))
  3381.       __strcat(line, "_x");
  3382. #endif
  3383.       if (i < nargs - 1)
  3384.     __strcat(line, ",");
  3385.     }
  3386.     __strcat(line, ")");
  3387.     DEC_Immediate(df, 1, 1, line);
  3388.  
  3389.     /*
  3390.      * if ( ( ( (s+1)->a != 1) && ( (s+1)->b != 1) && 
  3391.      * ( (s+2)->a != 1) && ( (s+2)->b != 1) ) || 
  3392.      * ( ((s+1)->op) % 100 == OP_CALL0 ) ) {
  3393.      * DEC_Indent(*indent);
  3394.      * fprintf(DEC_ofile,"%s;\n",line);
  3395.      * }
  3396.      */
  3397.     /* this SUCKS!!!!!!!!!!!!! */
  3398.     if ((((s + 1)->a != 1) && ((s + 1)->b != 1) &&
  3399.      ((s + 2)->a != 1) && ((s + 2)->b != 1)) ||
  3400.     ((((s + 1)->op) % 100 == OP_CALL0) && ((((s + 2)->a != 1)) || ((s + 2)->b != 1)))) {
  3401.       DEC_Indent(*indent);
  3402.       fprintf(DEC_ofile, "%s;\n", line);
  3403.     }
  3404.   }
  3405.   else if (s->op == OP_IF || s->op == OP_IFNOT) {
  3406.     arg1 = DEC_Get(df, s->a, NULL);
  3407.     arg2 = DEC_Global(s->a, NULL);
  3408.  
  3409.     if (s->op == OP_IFNOT) {
  3410.       if (s->b < 1) {
  3411.     eprintf("Found a negative IFNOT jump.");
  3412.     return;
  3413.       }
  3414.  
  3415.       /* get instruction right before the target */
  3416.       t = s + s->b - 1;
  3417.       tom = t->op % 100;
  3418.  
  3419.       if (tom != OP_GOTO) {
  3420.     /* pure if */
  3421.     DEC_Indent(*indent);
  3422.     fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3423.     (*indent)++;
  3424.       }
  3425.       else {
  3426.     if (t->a > 0) {
  3427.       /* ite */
  3428.       DEC_Indent(*indent);
  3429.       fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3430.       (*indent)++;
  3431.     }
  3432.     else {
  3433.       if ((t->a + s->b) > 1) {
  3434.         /* pure if  */
  3435.         DEC_Indent(*indent);
  3436.         fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3437.         (*indent)++;
  3438.       }
  3439.       else {
  3440.         dum = 1;
  3441.         for (k = t + (t->a); k < s; k++) {
  3442.           tom = k->op % 100;
  3443.           if (tom == OP_GOTO || tom == OP_IF || tom == OP_IFNOT)
  3444.         dum = 0;
  3445.         }
  3446.         if (dum) {
  3447.           /* while  */
  3448.           DEC_Indent(*indent);
  3449.           fprintf(DEC_ofile, "while ( %s ) {\n\n", arg1);
  3450.           (*indent)++;
  3451.         }
  3452.         else {
  3453.           /* pure if  */
  3454.           DEC_Indent(*indent);
  3455.           fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3456.           (*indent)++;
  3457.         }
  3458.       }
  3459.     }
  3460.       }
  3461.     }
  3462.     else {
  3463.       /* do ... while */
  3464.       (*indent)--;
  3465.       fprintf(DEC_ofile, "\n");
  3466.       DEC_Indent(*indent);
  3467.       fprintf(DEC_ofile, "} while ( %s );\n", arg1);
  3468.     }
  3469.   }
  3470.   else if (s->op == OP_GOTO) {
  3471.     if (s->a > 0) {
  3472.       /* else */
  3473.       (*indent)--;
  3474.       fprintf(DEC_ofile, "\n");
  3475.       DEC_Indent(*indent);
  3476.       fprintf(DEC_ofile, "} else {\n\n");
  3477.       (*indent)++;
  3478.     }
  3479.     else {
  3480.       /* while */
  3481.       (*indent)--;
  3482.       fprintf(DEC_ofile, "\n");
  3483.       DEC_Indent(*indent);
  3484.       fprintf(DEC_ofile, "}\n");
  3485.     }
  3486.   }
  3487.   else {
  3488.     fprintf(DEC_ofile, "\n/* ERROR: UNKNOWN COMMAND */\n");
  3489.   }
  3490.  
  3491.   oprintf("DEC_DecompileStatement - Current line is \"%s\"\n", line);
  3492.   if (arg1) {
  3493.     tfree(arg1);
  3494.     arg1 = 0;
  3495.   }
  3496.   if (arg2) {
  3497.     tfree(arg2);
  3498.     arg2 = 0;
  3499.   }
  3500.   if (arg3) {
  3501.     tfree(arg3);
  3502.     arg3 = 0;
  3503.   }
  3504.  
  3505.   return;
  3506. }
  3507.  
  3508. void DEC_DecompileFunction(register dfunction_t * df)
  3509. {
  3510.   dstatement_t *ds;
  3511.   int indent;
  3512.  
  3513.   /* Initialize */
  3514.   DEC_Immediate(df, 0, 0, NULL);
  3515.  
  3516.   indent = 1;
  3517.  
  3518.   ds = statements + df->first_statement;
  3519.   while (1) {
  3520.     DEC_DecompileStatement(df, ds, &indent);
  3521.     if (!ds->op)
  3522.       break;
  3523.     ds++;
  3524.   }
  3525.  
  3526.   if (indent != 1)
  3527.     fprintf(DEC_ofile, "/* ERROR : Indentiation structure corrupt */\n");
  3528. }
  3529.  
  3530. ddef_t *GetField(register char *name)
  3531. {
  3532.   int i;
  3533.   ddef_t *d;
  3534.  
  3535.   for (i = 1; i < numfielddefs; i++) {
  3536.     d = &fields[i];
  3537.  
  3538.     if (!__strcmp(strings + d->s_name, name))
  3539.       return d;
  3540.   }
  3541.   return NULL;
  3542. }
  3543.  
  3544. void DEC_Function(register char *name)
  3545. {
  3546.   int i, findex, ps;
  3547.   dstatement_t *ds, *ts;
  3548.   dfunction_t *df;
  3549.   ddef_t *par;
  3550.   char *arg2;
  3551.   unsigned short dom, tom;
  3552.  
  3553.   int j, start, end;
  3554.   dfunction_t *dfpred;
  3555.   ddef_t *ef;
  3556.  
  3557.   static char line[256];
  3558.  
  3559.   dstatement_t *k;
  3560.   int dum;
  3561.  
  3562.   for (i = 1; i < numfunctions; i++)
  3563.     if (!__strcmp(name, strings + functions[i].s_name))
  3564.       break;
  3565.   if (i == numfunctions) {
  3566.     eprintf("No function named \"%s\"", name);
  3567.     return;
  3568.   }
  3569.  
  3570.   df = functions + i;
  3571.  
  3572.   findex = i;
  3573.  
  3574.   /* Check ''local globals'' */
  3575.   dfpred = df - 1;
  3576.  
  3577.   for (j = 0, ps = 0; j < dfpred->numparms; j++)
  3578.     ps += dfpred->parm_size[j];
  3579.  
  3580.   start = dfpred->parm_start + dfpred->locals + ps;
  3581.  
  3582.   if (dfpred->first_statement < 0 && df->first_statement > 0)
  3583.     start -= 1;
  3584.  
  3585.   if (start == 0)
  3586.     start = 1;
  3587.  
  3588.   end = df->parm_start;
  3589.  
  3590.   for (j = start; j < end; j++) {
  3591.     par = DEC_GetParameter(j);
  3592.  
  3593.     if (par) {
  3594.       if (par->type & (1 << 15))
  3595.     par->type -= (1 << 15);
  3596.  
  3597.       if (par->type == ev_function) {
  3598.     if (__strcmp(strings + par->s_name, "IMMEDIATE"))
  3599.       if (__strcmp(strings + par->s_name, name)) {
  3600.         fprintf(DEC_ofile, "%s;\n", DEC_Profiles[DEC_GetFunctionIdxByName(strings + par->s_name)]);
  3601.       }
  3602.       }
  3603.       else if (par->type != ev_pointer)
  3604.     if (__strcmp(strings + par->s_name, "IMMEDIATE")) {
  3605.       if (par->type == ev_field) {
  3606.         ef = GetField(strings + par->s_name);
  3607.  
  3608.         if (!ef) {
  3609.           eprintf("Could not locate a field named \"%s\"", strings + par->s_name);
  3610.           return;
  3611.         }
  3612.  
  3613.         if (ef->type == ev_vector)
  3614.           j += 3;
  3615. #ifndef DONT_USE_DIRTY_TRICKS
  3616.         if ((ef->type == ev_function) && !__strcmp(strings + ef->s_name, "th_pain")) {
  3617.           fprintf(DEC_ofile, ".void(entity attacker, float damage) th_pain;\n");
  3618.         }
  3619.         else
  3620. #endif
  3621.           fprintf(DEC_ofile, ".%s %s;\n", type_names[ef->type], strings + ef->s_name);
  3622.       }
  3623.       else {
  3624.         if (par->type == ev_vector)
  3625.           j += 2;
  3626.         if (par->type == ev_entity || par->type == ev_void) {
  3627.           fprintf(DEC_ofile, "%s %s;\n", type_names[par->type], strings + par->s_name);
  3628.         }
  3629.         else {
  3630.           line[0] = '\0';
  3631.           sprintf(line, "%s", DEC_ValueString(par->type, &pr_globals[par->ofs]));
  3632.  
  3633.           if ((__strlen(strings + par->s_name) > 1) &&
  3634.           isupper((strings + par->s_name)[0]) &&
  3635.           (isupper((strings + par->s_name)[1]) || (strings + par->s_name)[1] == '_')) {
  3636.         fprintf(DEC_ofile, "%s %s    = %s;\n", type_names[par->type], strings + par->s_name, line);
  3637.           }
  3638.           else
  3639.         fprintf(DEC_ofile, "%s %s /* = %s */;\n", type_names[par->type], strings + par->s_name, line);
  3640.         }
  3641.       }
  3642.     }
  3643.     }
  3644.   }
  3645.   /* Check ''local globals'' */
  3646.   if (df->first_statement <= 0) {
  3647.     fprintf(DEC_ofile, "%s", DEC_Profiles[findex]);
  3648.     fprintf(DEC_ofile, " = #%i; \n", -df->first_statement);
  3649.     return;
  3650.   }
  3651.  
  3652.   ds = statements + df->first_statement;
  3653.  
  3654.   while (1) {
  3655.     dom = (ds->op) % 100;
  3656.  
  3657.     if (!dom)
  3658.       break;
  3659.     else if (dom == OP_GOTO) {
  3660.       /*
  3661.        * check for i-t-e 
  3662.        */
  3663.       if (ds->a > 0) {
  3664.     ts = ds + ds->a;
  3665.     /* mark the end of a if/ite construct */
  3666.     ts->op += 100;
  3667.       }
  3668.     }
  3669.     else if (dom == OP_IFNOT) {
  3670.       /*
  3671.        * check for pure if 
  3672.        */
  3673.       ts = ds + ds->b;
  3674.       tom = (ts - 1)->op % 100;
  3675.  
  3676.       if (tom != OP_GOTO)
  3677.     /* mark the end of a if/ite construct */
  3678.     ts->op += 100;
  3679.       else if ((ts - 1)->a < 0) {
  3680.     /*
  3681.      * arg2 = DEC_Global(ds->a,NULL);
  3682.      * 
  3683.      * if (!( ( ((ts-1)->a + ds->b) == 0)   || 
  3684.      * ( (arg2 != NULL) && (((ts-1)->a + ds->b) == 1) ))) 
  3685.      * (ts-1)->op += 100;
  3686.      * 
  3687.      * if (arg2) {
  3688.      *   tfree(arg2);
  3689.      *   arg2 = 0;
  3690.      * }
  3691.      */
  3692.     if (((ts - 1)->a + ds->b) > 1) {
  3693.       /* pure if  */
  3694.       /* mark the end of a if/ite construct */
  3695.       ts->op += 100;
  3696.     }
  3697.     else {
  3698.       dum = 1;
  3699.       for (k = (ts - 1) + ((ts - 1)->a); k < ds; k++) {
  3700.         tom = k->op % 100;
  3701.         if (tom == OP_GOTO || tom == OP_IF || tom == OP_IFNOT)
  3702.           dum = 0;
  3703.       }
  3704.       if (!dum) {
  3705.         /* pure if  */
  3706.         /* mark the end of a if/ite construct */
  3707.         ts->op += 100;
  3708.       }
  3709.     }
  3710.       }
  3711.     }
  3712.     else if (dom == OP_IF) {
  3713.       ts = ds + ds->b;
  3714.       /* mark the start of a do construct */
  3715.       ts->op += 10000;
  3716.     }
  3717.     ds++;
  3718.   }
  3719.  
  3720.   /* print the prototype */
  3721.   fprintf(DEC_ofile, "%s", DEC_Profiles[findex]);
  3722.  
  3723.   /* handle state functions */
  3724.   ds = statements + df->first_statement;
  3725.  
  3726.   if (ds->op == OP_STATE) {
  3727.     par = DEC_GetParameter(ds->a);
  3728.     if (!par) {
  3729.       eprintf("DEC_Function - Can't determine frame number.");
  3730.       return;
  3731.     }
  3732.  
  3733.     arg2 = DEC_Get(df, ds->b, NULL);
  3734.     if (!arg2) {
  3735.       eprintf("DEC_Function - No state parameter with offset %i.", ds->b);
  3736.       return;
  3737.     }
  3738.  
  3739.     fprintf(DEC_ofile, " = [ %s, %s ]", DEC_ValueString(par->type, &pr_globals[par->ofs]), arg2);
  3740.     tfree(arg2);
  3741.     arg2 = 0;
  3742.   }
  3743.   else {
  3744.     fprintf(DEC_ofile, " =");
  3745.   }
  3746.   fprintf(DEC_ofile, " {\n\n");
  3747.  
  3748. #ifdef    QC_PROFILE
  3749.   fprintf(DEC_profile, "%s", DEC_Profiles[findex]);
  3750.   fprintf(DEC_profile, ") %s;\n", name);
  3751. #endif
  3752.  
  3753.   /* calculate the parameter size */
  3754.   for (j = 0, ps = 0; j < df->numparms; j++)
  3755.     ps += df->parm_size[j];
  3756.  
  3757.   /* print the locals */
  3758.   if (df->locals > 0) {
  3759.     if ((df->parm_start) + df->locals - 1 >= (df->parm_start) + ps) {
  3760.       for (i = df->parm_start + ps; i < (df->parm_start) + df->locals; i++) {
  3761.     par = DEC_GetParameter(i);
  3762.  
  3763.     if (!par) {
  3764.       fprintf(DEC_ofile, "   /* ERROR: No local name with offset %i */\n", i);
  3765.     }
  3766.     else {
  3767.       if (par->type == ev_function)
  3768.         fprintf(DEC_ofile, "   /* ERROR: Fields and functions must be global */\n");
  3769.       else
  3770.         fprintf(DEC_ofile, "   local %s;\n", DEC_PrintParameter(par));
  3771.       if (par->type == ev_vector)
  3772.         i += 2;
  3773.     }
  3774.       }
  3775.  
  3776.       fprintf(DEC_ofile, "\n");
  3777.     }
  3778.   }
  3779.  
  3780.   /* do the hard work */
  3781.   DEC_DecompileFunction(df);
  3782.   fprintf(DEC_ofile, "\n};\n");
  3783. }
  3784.  
  3785. bool DEC_DecompileFunctions(register char *destDir)
  3786. {
  3787.   int i;
  3788.   dfunction_t *d;
  3789.   FILE *f;
  3790.   char fname[512];
  3791.  
  3792.   DEC_CalcProfiles();
  3793.  
  3794.   fname[0] = '\0';
  3795.   sprintf(fname, "%s%s", destDir, "progs.src");
  3796.   DEC_progssrc = fopen(fname, "w");
  3797.   if (!DEC_progssrc) {
  3798.     eprintf("DEC_DecompileFunctions - Could not open \"progs.src\" for output.");
  3799.     return FALSE;
  3800.   }
  3801.  
  3802.   fprintf(DEC_progssrc, "./progs.dat\n\n");
  3803.  
  3804. #ifdef    QC_PROFILE
  3805.   DEC_profile = fopen("!profile.qc", "w");
  3806.   if (!DEC_profile)
  3807.     Error("DEC_DecompileFunctions - Could not open \"!profile.qc\" for output.");
  3808.   fprintf(DEC_progssrc, "!profile.qc\n");
  3809. #endif
  3810.  
  3811.   for (i = 1; i < numfunctions; i++) {
  3812.     d = &functions[i];
  3813.  
  3814.     fname[0] = '\0';
  3815.     sprintf(fname, "%s%s", destDir, strings + d->s_file);
  3816.     f = fopen(fname, "a+");
  3817.  
  3818.     if (!DEC_AlreadySeen(fname))
  3819.       fprintf(DEC_progssrc, "%s\n", fname);
  3820.  
  3821.     if (!f) {
  3822.       eprintf("DEC_DecompileFunctions - Could not open \"%s\" for output.", fname);
  3823.       return FALSE;
  3824.     }
  3825.     DEC_ofile = f;
  3826.     DEC_Function(strings + d->s_name);
  3827.  
  3828.     if (fclose(f)) {
  3829.       eprintf("DEC_DecompileFunctions - Could not close \"%s\" properly.", fname);
  3830.       return FALSE;
  3831.     }
  3832.   }
  3833.  
  3834.   if (fclose(DEC_progssrc)) {
  3835.     eprintf("DEC_DecompileFunctions - Could not close \"progs.src\" properly.");
  3836.     return FALSE;
  3837.   }
  3838.  
  3839. #ifdef    QC_PROFILE
  3840.   if (fclose(DEC_profile))
  3841.     Error("DEC_DecompileFunctions - Could not close \"!profile.qc\" properly.");
  3842. #endif
  3843.   return TRUE;
  3844. }
  3845.  
  3846. char *DEC_GlobalStringNoContents(register gofs_t ofs)
  3847. {
  3848.   int i;
  3849.   ddef_t *def;
  3850.   static char line[128];
  3851.  
  3852.   line[0] = '0';
  3853.   sprintf(line, "%i(???)", ofs);
  3854.  
  3855.   for (i = 0; i < numglobaldefs; i++) {
  3856.     def = &globals[i];
  3857.  
  3858.     if (def->ofs == ofs) {
  3859.       line[0] = '0';
  3860.       sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
  3861.       break;
  3862.     }
  3863.   }
  3864.  
  3865.   i = __strlen(line);
  3866.   for (; i < 16; i++)
  3867.     __strcat(line, " ");
  3868.   __strcat(line, " ");
  3869.  
  3870.   return line;
  3871. }
  3872.  
  3873. char *DEC_GlobalString(register gofs_t ofs)
  3874. {
  3875.   char *s;
  3876.   int i;
  3877.   ddef_t *def;
  3878.   static char line[128];
  3879.  
  3880.   line[0] = '0';
  3881.   sprintf(line, "%i(???)", ofs);
  3882.  
  3883.   for (i = 0; i < numglobaldefs; i++) {
  3884.     def = &globals[i];
  3885.  
  3886.     if (def->ofs == ofs) {
  3887.  
  3888.       line[0] = '0';
  3889.       if (!__strcmp(strings + def->s_name, "IMMEDIATE")) {
  3890.     s = PR_ValueString(def->type, &pr_globals[ofs]);
  3891.     sprintf(line, "%i(%s)", def->ofs, s);
  3892.       }
  3893.       else
  3894.     sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
  3895.     }
  3896.   }
  3897.  
  3898.   i = __strlen(line);
  3899.   for (; i < 16; i++)
  3900.     __strcat(line, " ");
  3901.   __strcat(line, " ");
  3902.  
  3903.   return line;
  3904. }
  3905.  
  3906. /*
  3907.  * fix: same as PR_PrintStatement
  3908.  *  mprintf("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s - statements], pr_opcodes[s->op].opname);
  3909.  */
  3910. void DEC_PrintStatement(register dstatement_t * s)
  3911. {
  3912.   int i;
  3913.  
  3914.   mprintf("%4i : %s ", (int)(s - statements), pr_opcodes[s->op].opname);
  3915.   i = __strlen(pr_opcodes[s->op].opname);
  3916.   for (; i < 10; i++)
  3917.     mprintf(" ");
  3918.  
  3919.   if (s->op == OP_IF || s->op == OP_IFNOT)
  3920.     mprintf("%sbranch %i", DEC_GlobalString(s->a), s->b);
  3921.   else if (s->op == OP_GOTO) {
  3922.     mprintf("branch %i", s->a);
  3923.   }
  3924.   else if ((unsigned)(s->op - OP_STORE_F) < 6) {
  3925.     mprintf("%s", DEC_GlobalString(s->a));
  3926.     mprintf("%s", DEC_GlobalStringNoContents(s->b));
  3927.   }
  3928.   else {
  3929.     if (s->a)
  3930.       mprintf("%s", DEC_GlobalString(s->a));
  3931.     if (s->b)
  3932.       mprintf("%s", DEC_GlobalString(s->b));
  3933.     if (s->c)
  3934.       mprintf("%s", DEC_GlobalStringNoContents(s->c));
  3935.   }
  3936.   mprintf("\n");
  3937. }
  3938.  
  3939. /*
  3940.  * fix: same as PrintFunction
  3941.  */
  3942. void DEC_PrintFunction(register char *name)
  3943. {
  3944.   int i;
  3945.   dstatement_t *ds;
  3946.   dfunction_t *df;
  3947.  
  3948.   for (i = 0; i < numfunctions; i++)
  3949.     if (!__strcmp(name, strings + functions[i].s_name))
  3950.       break;
  3951.   if (i == numfunctions)
  3952.     eprintf("No function names \"%s\"", name);
  3953.   else {
  3954.     df = functions + i;
  3955.  
  3956.     mprintf("Statements for %s:\n", name);
  3957.     ds = statements + df->first_statement;
  3958.     while (1) {
  3959.       DEC_PrintStatement(ds);
  3960.  
  3961.       if (!ds->op)
  3962.     break;
  3963.  
  3964.       ds++;
  3965.     }
  3966.   }
  3967. }
  3968.  
  3969. /*=========================================================================== */
  3970. /*interface */
  3971. /*=========================================================================== */
  3972.  
  3973. bool qcc(FILE * srcFile, char *srcDir, operation procOper)
  3974. {
  3975.   char *srcData, *srcFree = 0;
  3976.   char *srcPart;
  3977.   char fileName[1024];
  3978.   void *freeIt = 0;
  3979.   bool failure = FALSE;
  3980.  
  3981.   if (InitData()) {
  3982.     switch (procOper) {
  3983.       case OP_ADD:
  3984.     __strcpy(sourcedir, srcDir);
  3985.     if (!(srcData = srcFree = (char *)GetVoidF(fileno(srcFile))))
  3986.       break;
  3987.  
  3988.     if (!(srcData = COM_Parse(srcData))) {
  3989.       eprintf("No destination fileName.\n");
  3990.       tfree(srcFree);
  3991.       srcFree = 0;
  3992.       break;
  3993.     }
  3994.  
  3995.     __strcpy(destfile, com_token);
  3996.     mprintf("outputfile: %s\n", destfile);
  3997.  
  3998.     pr_dumpasm = FALSE;
  3999.     PR_BeginCompilation(freeIt = (void *)kmalloc(0x100000), 0x100000);
  4000.  
  4001.     /* compile all the files */
  4002.     do {
  4003.       if (!(srcData = COM_Parse(srcData)))
  4004.         break;
  4005.  
  4006.       sprintf(fileName, "%s%s", sourcedir, com_token);
  4007.       mprintf("compiling %s\n", fileName);
  4008.       if (!(srcPart = (char *)GetPreProcessed(fileName))) {
  4009.         eprintf(failed_fileopen, fileName);
  4010.         failure = TRUE;
  4011.         break;
  4012.       }
  4013.  
  4014.       if (!PR_CompileFile(srcPart, fileName)) {
  4015.         eprintf("cannot compile %s\n", fileName);
  4016.         tfree(srcPart);
  4017.         srcPart = 0;
  4018.         failure = TRUE;
  4019.         break;
  4020.       }
  4021.       else {
  4022.         tfree(srcPart);
  4023.         srcPart = 0;
  4024.       }
  4025.     } while (1);
  4026.  
  4027.     if (!failure) {
  4028.       if (PR_FinishCompilation()) {
  4029.         /* write progdefs.h */
  4030.         sprintf(fileName, "%s%s", sourcedir, "progdefs.h");
  4031.         /* write data file */
  4032.         WriteData(PR_WriteProgdefs(fileName));
  4033.         /* write files.dat */
  4034.         WriteFiles();
  4035.       }
  4036.       else
  4037.         eprintf("compilation errors\n");
  4038.     }
  4039.     else
  4040.       eprintf("compilation errors\n");
  4041.  
  4042.     tfree(srcFree);
  4043.     srcFree = 0;
  4044.     break;
  4045.       default:
  4046.     break;
  4047.     }
  4048.     ExitData();
  4049.     return TRUE;
  4050.   }
  4051.   else
  4052.     return FALSE;
  4053. }
  4054.  
  4055. bool unqcc(HANDLE srcFile, char *destDir, operation procOper)
  4056. {
  4057.   bool retval = FALSE;
  4058.  
  4059.   switch (procOper) {
  4060.     case OP_EXTRACT:
  4061.       if (ReadData(srcFile)) {
  4062.     CreatePath(destDir);
  4063.     retval = DEC_DecompileFunctions(destDir);
  4064.       }
  4065.       else
  4066.     eprintf("decompilation error!\n");
  4067.       break;
  4068.     case OP_LIST:
  4069.     default:
  4070.       retval = ShowData(srcFile);
  4071.       break;
  4072.   }
  4073.  
  4074.   ExitData();
  4075.   return retval;
  4076. }
  4077.